sorcery 0.9.0 → 0.10.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +29 -104
  3. data/CHANGELOG.md +22 -1
  4. data/Gemfile +2 -16
  5. data/README.md +124 -271
  6. data/Rakefile +2 -2
  7. data/gemfiles/{mongoid-rails40.gemfile → active_record-rails42.gemfile} +1 -3
  8. data/lib/generators/sorcery/helpers.rb +4 -4
  9. data/lib/generators/sorcery/install_generator.rb +25 -19
  10. data/lib/generators/sorcery/templates/initializer.rb +29 -53
  11. data/lib/generators/sorcery/templates/migration/activity_logging.rb +2 -2
  12. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +1 -1
  13. data/lib/generators/sorcery/templates/migration/core.rb +3 -3
  14. data/lib/generators/sorcery/templates/migration/external.rb +3 -3
  15. data/lib/generators/sorcery/templates/migration/remember_me.rb +2 -2
  16. data/lib/generators/sorcery/templates/migration/reset_password.rb +2 -2
  17. data/lib/generators/sorcery/templates/migration/user_activation.rb +2 -2
  18. data/lib/sorcery/adapters/active_record_adapter.rb +7 -18
  19. data/lib/sorcery/controller/config.rb +20 -18
  20. data/lib/sorcery/controller/submodules/activity_logging.rb +7 -15
  21. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
  22. data/lib/sorcery/controller/submodules/external.rb +23 -15
  23. data/lib/sorcery/controller/submodules/http_basic_auth.rb +16 -19
  24. data/lib/sorcery/controller/submodules/remember_me.rb +15 -10
  25. data/lib/sorcery/controller/submodules/session_timeout.rb +7 -8
  26. data/lib/sorcery/controller.rb +19 -21
  27. data/lib/sorcery/crypto_providers/aes256.rb +15 -15
  28. data/lib/sorcery/crypto_providers/bcrypt.rb +19 -21
  29. data/lib/sorcery/crypto_providers/common.rb +1 -1
  30. data/lib/sorcery/crypto_providers/md5.rb +5 -5
  31. data/lib/sorcery/crypto_providers/sha1.rb +5 -5
  32. data/lib/sorcery/crypto_providers/sha256.rb +2 -2
  33. data/lib/sorcery/crypto_providers/sha512.rb +3 -3
  34. data/lib/sorcery/engine.rb +3 -8
  35. data/lib/sorcery/model/config.rb +64 -49
  36. data/lib/sorcery/model/submodules/activity_logging.rb +31 -12
  37. data/lib/sorcery/model/submodules/brute_force_protection.rb +23 -23
  38. data/lib/sorcery/model/submodules/external.rb +3 -7
  39. data/lib/sorcery/model/submodules/remember_me.rb +19 -7
  40. data/lib/sorcery/model/submodules/reset_password.rb +32 -36
  41. data/lib/sorcery/model/submodules/user_activation.rb +38 -50
  42. data/lib/sorcery/model/temporary_token.rb +2 -2
  43. data/lib/sorcery/model.rb +27 -31
  44. data/lib/sorcery/protocols/oauth.rb +3 -9
  45. data/lib/sorcery/protocols/oauth2.rb +0 -2
  46. data/lib/sorcery/providers/base.rb +4 -4
  47. data/lib/sorcery/providers/facebook.rb +17 -9
  48. data/lib/sorcery/providers/github.rb +12 -5
  49. data/lib/sorcery/providers/google.rb +3 -5
  50. data/lib/sorcery/providers/heroku.rb +6 -8
  51. data/lib/sorcery/providers/jira.rb +12 -17
  52. data/lib/sorcery/providers/linkedin.rb +6 -8
  53. data/lib/sorcery/providers/liveid.rb +4 -7
  54. data/lib/sorcery/providers/paypal.rb +60 -0
  55. data/lib/sorcery/providers/salesforce.rb +3 -5
  56. data/lib/sorcery/providers/slack.rb +45 -0
  57. data/lib/sorcery/providers/twitter.rb +4 -6
  58. data/lib/sorcery/providers/vk.rb +3 -5
  59. data/lib/sorcery/providers/wechat.rb +79 -0
  60. data/lib/sorcery/providers/xing.rb +8 -11
  61. data/lib/sorcery/test_helpers/internal/rails.rb +16 -8
  62. data/lib/sorcery/test_helpers/internal.rb +10 -10
  63. data/lib/sorcery/test_helpers/rails/controller.rb +1 -1
  64. data/lib/sorcery/test_helpers/rails/integration.rb +5 -6
  65. data/lib/sorcery/version.rb +1 -1
  66. data/lib/sorcery.rb +0 -28
  67. data/sorcery.gemspec +25 -27
  68. data/spec/active_record/user_activation_spec.rb +2 -3
  69. data/spec/active_record/user_activity_logging_spec.rb +2 -4
  70. data/spec/active_record/user_brute_force_protection_spec.rb +3 -4
  71. data/spec/active_record/user_oauth_spec.rb +3 -4
  72. data/spec/active_record/user_remember_me_spec.rb +3 -4
  73. data/spec/active_record/user_reset_password_spec.rb +2 -3
  74. data/spec/active_record/user_spec.rb +7 -7
  75. data/spec/controllers/controller_activity_logging_spec.rb +13 -24
  76. data/spec/controllers/controller_brute_force_protection_spec.rb +6 -8
  77. data/spec/controllers/controller_http_basic_auth_spec.rb +19 -20
  78. data/spec/controllers/controller_oauth2_spec.rb +142 -102
  79. data/spec/controllers/controller_oauth_spec.rb +86 -66
  80. data/spec/controllers/controller_remember_me_spec.rb +35 -30
  81. data/spec/controllers/controller_session_timeout_spec.rb +14 -15
  82. data/spec/controllers/controller_spec.rb +77 -111
  83. data/spec/orm/active_record.rb +1 -1
  84. data/spec/rails_app/app/active_record/authentication.rb +1 -1
  85. data/spec/rails_app/app/active_record/user.rb +2 -2
  86. data/spec/rails_app/app/controllers/sorcery_controller.rb +89 -24
  87. data/spec/rails_app/app/mailers/sorcery_mailer.rb +16 -17
  88. data/spec/rails_app/config/application.rb +7 -7
  89. data/spec/rails_app/config/boot.rb +1 -1
  90. data/spec/rails_app/config/environments/test.rb +1 -1
  91. data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +11 -0
  92. data/spec/rails_app/config/initializers/session_store.rb +3 -3
  93. data/spec/rails_app/config/routes.rb +11 -1
  94. data/spec/rails_app/config.ru +1 -1
  95. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +4 -4
  96. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +8 -8
  97. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +5 -5
  98. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +5 -5
  99. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +3 -3
  100. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +6 -6
  101. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +5 -5
  102. data/spec/shared_examples/user_activation_shared_examples.rb +99 -58
  103. data/spec/shared_examples/user_activity_logging_shared_examples.rb +47 -41
  104. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +19 -24
  105. data/spec/shared_examples/user_oauth_shared_examples.rb +7 -10
  106. data/spec/shared_examples/user_remember_me_shared_examples.rb +90 -21
  107. data/spec/shared_examples/user_reset_password_shared_examples.rb +52 -54
  108. data/spec/shared_examples/user_shared_examples.rb +226 -116
  109. data/spec/sorcery_crypto_providers_spec.rb +63 -76
  110. data/spec/spec_helper.rb +17 -13
  111. metadata +28 -82
  112. data/gemfiles/mongo_mapper-rails40.gemfile +0 -9
  113. data/gemfiles/mongo_mapper-rails41.gemfile +0 -9
  114. data/gemfiles/mongoid-rails41.gemfile +0 -9
  115. data/gemfiles/mongoid3-rails32.gemfile +0 -9
  116. data/lib/sorcery/adapters/data_mapper_adapter.rb +0 -176
  117. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +0 -110
  118. data/lib/sorcery/adapters/mongoid_adapter.rb +0 -97
  119. data/lib/sorcery/railties/tasks.rake +0 -6
  120. data/spec/data_mapper/user_activation_spec.rb +0 -10
  121. data/spec/data_mapper/user_activity_logging_spec.rb +0 -14
  122. data/spec/data_mapper/user_brute_force_protection_spec.rb +0 -9
  123. data/spec/data_mapper/user_oauth_spec.rb +0 -9
  124. data/spec/data_mapper/user_remember_me_spec.rb +0 -8
  125. data/spec/data_mapper/user_reset_password_spec.rb +0 -8
  126. data/spec/data_mapper/user_spec.rb +0 -27
  127. data/spec/mongo_mapper/user_activation_spec.rb +0 -9
  128. data/spec/mongo_mapper/user_activity_logging_spec.rb +0 -8
  129. data/spec/mongo_mapper/user_brute_force_protection_spec.rb +0 -8
  130. data/spec/mongo_mapper/user_oauth_spec.rb +0 -8
  131. data/spec/mongo_mapper/user_remember_me_spec.rb +0 -8
  132. data/spec/mongo_mapper/user_reset_password_spec.rb +0 -8
  133. data/spec/mongo_mapper/user_spec.rb +0 -37
  134. data/spec/mongoid/user_activation_spec.rb +0 -9
  135. data/spec/mongoid/user_activity_logging_spec.rb +0 -8
  136. data/spec/mongoid/user_brute_force_protection_spec.rb +0 -8
  137. data/spec/mongoid/user_oauth_spec.rb +0 -8
  138. data/spec/mongoid/user_remember_me_spec.rb +0 -8
  139. data/spec/mongoid/user_reset_password_spec.rb +0 -8
  140. data/spec/mongoid/user_spec.rb +0 -51
  141. data/spec/orm/data_mapper.rb +0 -48
  142. data/spec/orm/mongo_mapper.rb +0 -10
  143. data/spec/orm/mongoid.rb +0 -22
  144. data/spec/rails_app/app/data_mapper/authentication.rb +0 -8
  145. data/spec/rails_app/app/data_mapper/user.rb +0 -7
  146. data/spec/rails_app/app/mongo_mapper/authentication.rb +0 -6
  147. data/spec/rails_app/app/mongo_mapper/user.rb +0 -7
  148. data/spec/rails_app/app/mongoid/authentication.rb +0 -7
  149. data/spec/rails_app/app/mongoid/user.rb +0 -7
  150. data/spec/rails_app/log/development.log +0 -1791
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  # require 'shared_examples/controller_oauth2_shared_examples'
4
4
 
5
- describe SorceryController, :active_record => true do
5
+ describe SorceryController, active_record: true, type: :controller do
6
6
  before(:all) do
7
7
  if SORCERY_ORM == :active_record
8
8
  ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
@@ -26,45 +26,44 @@ describe SorceryController, :active_record => true do
26
26
 
27
27
  it 'creates a new user' do
28
28
  sorcery_model_property_set(:authentications_class, Authentication)
29
- sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' })
29
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name')
30
30
 
31
- expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'})
32
- get :test_create_from_provider, provider: 'facebook'
31
+ expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari')
32
+ get :test_create_from_provider, params: { provider: 'facebook' }
33
33
  end
34
34
 
35
35
  it 'supports nested attributes' do
36
36
  sorcery_model_property_set(:authentications_class, Authentication)
37
- sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'hometown/name' })
38
- expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Haifa, Israel'})
37
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'hometown/name')
38
+ expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Haifa, Israel')
39
39
 
40
- get :test_create_from_provider, provider: 'facebook'
40
+ get :test_create_from_provider, params: { provider: 'facebook' }
41
41
  end
42
42
 
43
43
  it 'does not crash on missing nested attributes' do
44
44
  sorcery_model_property_set(:authentications_class, Authentication)
45
- sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name', created_at: 'does/not/exist' })
45
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name', created_at: 'does/not/exist')
46
46
 
47
- expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'})
47
+ expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari')
48
48
 
49
- get :test_create_from_provider, provider: 'facebook'
49
+ get :test_create_from_provider, params: { provider: 'facebook' }
50
50
  end
51
51
 
52
52
  describe 'with a block' do
53
53
  it 'does not create user' do
54
54
  sorcery_model_property_set(:authentications_class, Authentication)
55
- sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' })
55
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name')
56
56
 
57
57
  u = double('user')
58
- expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}).and_return(u).and_yield(u)
58
+ expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari').and_return(u).and_yield(u)
59
59
  # test_create_from_provider_with_block in controller will check for uniqueness of username
60
- get :test_create_from_provider_with_block, provider: 'facebook'
60
+ get :test_create_from_provider_with_block, params: { provider: 'facebook' }
61
61
  end
62
62
  end
63
63
  end
64
64
 
65
65
  # ----------------- OAuth -----------------------
66
- context "with OAuth features" do
67
-
66
+ context 'with OAuth features' do
68
67
  let(:user) { double('user', id: 42) }
69
68
 
70
69
  before(:each) do
@@ -76,36 +75,51 @@ describe SorceryController, :active_record => true do
76
75
  Authentication.sorcery_adapter.delete_all
77
76
  end
78
77
 
79
- context "when callback_url begin with /" do
78
+ context 'when callback_url begin with /' do
80
79
  before do
81
- sorcery_controller_external_property_set(:facebook, :callback_url, "/oauth/twitter/callback")
80
+ sorcery_controller_external_property_set(:facebook, :callback_url, '/oauth/twitter/callback')
82
81
  end
83
- it "login_at redirects correctly" do
82
+ it 'login_at redirects correctly' do
84
83
  get :login_at_test_facebook
85
84
  expect(response).to be_a_redirect
86
- expect(response).to redirect_to("https://graph.facebook.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email%2Coffline_access&state=")
85
+ expect(response).to redirect_to("https://www.facebook.com/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state")
86
+ end
87
+
88
+ it 'logins with state' do
89
+ get :login_at_test_with_state
90
+ expect(response).to be_a_redirect
91
+ expect(response).to redirect_to("https://www.facebook.com/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla")
87
92
  end
88
- it "logins with state" do
93
+
94
+ it 'logins with Graph API version' do
95
+ sorcery_controller_external_property_set(:facebook, :api_version, 'v2.2')
89
96
  get :login_at_test_with_state
90
97
  expect(response).to be_a_redirect
91
- expect(response).to redirect_to("https://graph.facebook.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email%2Coffline_access&state=bla")
98
+ expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla")
99
+ end
100
+
101
+ it 'logins without state after login with state' do
102
+ get :login_at_test_with_state
103
+ expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla")
104
+
105
+ get :login_at_test_facebook
106
+ expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state")
92
107
  end
108
+
93
109
  after do
94
- sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
110
+ sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com')
95
111
  end
96
112
  end
97
113
 
98
- #this test can never pass because of the previous test (the callback url can't change anymore)
99
- =begin
100
- context "when callback_url begin with http://" do
101
- it "login_at redirects correctly" do
114
+ context 'when callback_url begin with http://' do
115
+ it 'login_at redirects correctly' do
102
116
  create_new_user
103
- get :login_at_test2
104
- response.should be_a_redirect
105
- response.should redirect_to("https://graph.facebook.com/oauth/authorize?response_type=code&client_id=#{::Sorcery::Controller::Config.facebook.key}&redirect_uri=http%3A%2F%2Fblabla.com&scope=email%2Coffline_access&display=page&state")
117
+ get :login_at_test_facebook
118
+ expect(response).to be_a_redirect
119
+ expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state")
106
120
  end
107
121
  end
108
- =end
122
+
109
123
  it "'login_from' logins if user exists" do
110
124
  # dirty hack for rails 4
111
125
  allow(subject).to receive(:register_last_activity_time_to_db)
@@ -114,7 +128,7 @@ describe SorceryController, :active_record => true do
114
128
  expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user)
115
129
  get :test_login_from_facebook
116
130
 
117
- expect(flash[:notice]).to eq "Success!"
131
+ expect(flash[:notice]).to eq 'Success!'
118
132
  end
119
133
 
120
134
  it "'login_from' fails if user doesn't exist" do
@@ -122,30 +136,28 @@ describe SorceryController, :active_record => true do
122
136
  expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(nil)
123
137
  get :test_login_from_facebook
124
138
 
125
- expect(flash[:alert]).to eq "Failed!"
139
+ expect(flash[:alert]).to eq 'Failed!'
126
140
  end
127
141
 
128
- it "on successful login_from the user is redirected to the url he originally wanted" do
142
+ it 'on successful login_from the user is redirected to the url he originally wanted' do
129
143
  # dirty hack for rails 4
130
144
  allow(subject).to receive(:register_last_activity_time_to_db)
131
145
 
132
146
  sorcery_model_property_set(:authentications_class, Authentication)
133
147
  expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user)
134
- get :test_return_to_with_external_facebook, {}, :return_to_url => "fuu"
148
+ get :test_return_to_with_external_facebook, params: {}, session: { return_to_url: 'fuu' }
135
149
 
136
- expect(response).to redirect_to("fuu")
137
- expect(flash[:notice]).to eq "Success!"
150
+ expect(response).to redirect_to('fuu')
151
+ expect(flash[:notice]).to eq 'Success!'
138
152
  end
139
153
 
140
- [:github, :google, :liveid, :vk, :salesforce].each do |provider|
141
-
154
+ [:github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat].each do |provider|
142
155
  describe "with #{provider}" do
143
-
144
- it "login_at redirects correctly" do
156
+ it 'login_at redirects correctly' do
145
157
  get :"login_at_test_#{provider}"
146
158
 
147
159
  expect(response).to be_a_redirect
148
- expect(response).to redirect_to(provider_url provider)
160
+ expect(response).to redirect_to(provider_url(provider))
149
161
  end
150
162
 
151
163
  it "'login_from' logins if user exists" do
@@ -156,7 +168,7 @@ describe SorceryController, :active_record => true do
156
168
  expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user)
157
169
  get :"test_login_from_#{provider}"
158
170
 
159
- expect(flash[:notice]).to eq "Success!"
171
+ expect(flash[:notice]).to eq 'Success!'
160
172
  end
161
173
 
162
174
  it "'login_from' fails if user doesn't exist" do
@@ -164,7 +176,7 @@ describe SorceryController, :active_record => true do
164
176
  expect(User).to receive(:load_from_provider).with(provider, '123').and_return(nil)
165
177
  get :"test_login_from_#{provider}"
166
178
 
167
- expect(flash[:alert]).to eq "Failed!"
179
+ expect(flash[:alert]).to eq 'Failed!'
168
180
  end
169
181
 
170
182
  it "on successful login_from the user is redirected to the url he originally wanted (#{provider})" do
@@ -173,25 +185,25 @@ describe SorceryController, :active_record => true do
173
185
 
174
186
  sorcery_model_property_set(:authentications_class, Authentication)
175
187
  expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user)
176
- get :"test_return_to_with_external_#{provider}", {}, :return_to_url => "fuu"
188
+ get :"test_return_to_with_external_#{provider}", params: {}, session: { return_to_url: 'fuu' }
177
189
 
178
- expect(response).to redirect_to "fuu"
179
- expect(flash[:notice]).to eq "Success!"
190
+ expect(response).to redirect_to 'fuu'
191
+ expect(flash[:notice]).to eq 'Success!'
180
192
  end
181
193
  end
182
194
  end
183
-
184
195
  end
185
196
 
186
- describe "OAuth with User Activation features" do
197
+ describe 'OAuth with User Activation features' do
187
198
  before(:all) do
188
199
  if SORCERY_ORM == :active_record
189
200
  ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
190
201
  end
191
202
 
192
203
  sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
193
- sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce])
204
+ sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat])
194
205
 
206
+ # TODO: refactor
195
207
  sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
196
208
  sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
197
209
  sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
@@ -210,10 +222,20 @@ describe SorceryController, :active_record => true do
210
222
  sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w")
211
223
  sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
212
224
  sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com")
225
+ sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w")
226
+ sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
227
+ sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com")
228
+ sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w")
229
+ sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
230
+ sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com")
231
+ sorcery_controller_external_property_set(:wechat, :key, "eYVNBjBDi33aa9GkA3w")
232
+ sorcery_controller_external_property_set(:wechat, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
233
+ sorcery_controller_external_property_set(:wechat, :callback_url, "http://blabla.com")
213
234
  end
214
235
 
215
236
  after(:all) do
216
237
  if SORCERY_ORM == :active_record
238
+ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
217
239
  ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
218
240
  end
219
241
  end
@@ -222,14 +244,14 @@ describe SorceryController, :active_record => true do
222
244
  User.sorcery_adapter.delete_all
223
245
  end
224
246
 
225
- it "does not send activation email to external users" do
247
+ it 'does not send activation email to external users' do
226
248
  old_size = ActionMailer::Base.deliveries.size
227
249
  create_new_external_user(:facebook)
228
250
 
229
251
  expect(ActionMailer::Base.deliveries.size).to eq old_size
230
252
  end
231
253
 
232
- it "does not send external users an activation success email" do
254
+ it 'does not send external users an activation success email' do
233
255
  sorcery_model_property_set(:activation_success_email_method_name, nil)
234
256
  create_new_external_user(:facebook)
235
257
  old_size = ActionMailer::Base.deliveries.size
@@ -238,7 +260,7 @@ describe SorceryController, :active_record => true do
238
260
  expect(ActionMailer::Base.deliveries.size).to eq old_size
239
261
  end
240
262
 
241
- [:github, :google, :liveid, :vk, :salesforce].each do |provider|
263
+ [:github, :google, :liveid, :vk, :salesforce, :paypal, :wechat].each do |provider|
242
264
  it "does not send activation email to external users (#{provider})" do
243
265
  old_size = ActionMailer::Base.deliveries.size
244
266
  create_new_external_user provider
@@ -254,8 +276,7 @@ describe SorceryController, :active_record => true do
254
276
  end
255
277
  end
256
278
 
257
- describe "OAuth with user activation features" do
258
-
279
+ describe 'OAuth with user activation features' do
259
280
  let(:user) { double('user', id: 42) }
260
281
 
261
282
  before(:all) do
@@ -269,7 +290,7 @@ describe SorceryController, :active_record => true do
269
290
  end
270
291
  end
271
292
 
272
- %w(facebook github google liveid vk salesforce).each do |provider|
293
+ %w(facebook github google liveid vk salesforce slack).each do |provider|
273
294
  context "when #{provider}" do
274
295
  before(:each) do
275
296
  sorcery_controller_property_set(:register_login_time, true)
@@ -280,7 +301,7 @@ describe SorceryController, :active_record => true do
280
301
  sorcery_model_property_set(:authentications_class, Authentication)
281
302
  end
282
303
 
283
- it "registers login time" do
304
+ it 'registers login time' do
284
305
  now = Time.now.in_time_zone
285
306
  Timecop.freeze(now)
286
307
  expect(User).to receive(:load_from_provider).and_return(user)
@@ -289,31 +310,30 @@ describe SorceryController, :active_record => true do
289
310
  Timecop.return
290
311
  end
291
312
 
292
- it "does not register login time if configured so" do
313
+ it 'does not register login time if configured so' do
293
314
  sorcery_controller_property_set(:register_login_time, false)
294
315
  now = Time.now.in_time_zone
295
316
  Timecop.freeze(now)
296
317
  expect(User).to receive(:load_from_provider).and_return(user)
297
318
  expect(user).to receive(:set_last_login_at).never
298
319
  get "test_login_from_#{provider}".to_sym
299
-
300
320
  end
301
321
  end
302
322
  end
303
323
  end
304
324
 
305
- describe "OAuth with session timeout features" do
325
+ describe 'OAuth with session timeout features' do
306
326
  before(:all) do
307
327
  sorcery_reload!([:session_timeout, :external])
308
328
  end
309
329
 
310
330
  let(:user) { double('user', id: 42) }
311
331
 
312
- %w(facebook github google liveid vk salesforce).each do |provider|
332
+ %w(facebook github google liveid vk salesforce slack).each do |provider|
313
333
  context "when #{provider}" do
314
334
  before(:each) do
315
335
  sorcery_model_property_set(:authentications_class, Authentication)
316
- sorcery_controller_property_set(:session_timeout,0.5)
336
+ sorcery_controller_property_set(:session_timeout, 0.5)
317
337
  stub_all_oauth2_requests!
318
338
  end
319
339
 
@@ -321,19 +341,19 @@ describe SorceryController, :active_record => true do
321
341
  Timecop.return
322
342
  end
323
343
 
324
- it "does not reset session before session timeout" do
344
+ it 'does not reset session before session timeout' do
325
345
  expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user)
326
346
  get "test_login_from_#{provider}".to_sym
327
347
 
328
348
  expect(session[:user_id]).not_to be_nil
329
- expect(flash[:notice]).to eq "Success!"
349
+ expect(flash[:notice]).to eq 'Success!'
330
350
  end
331
351
 
332
- it "resets session after session timeout" do
352
+ it 'resets session after session timeout' do
333
353
  expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user)
334
354
  get "test_login_from_#{provider}".to_sym
335
- expect(session[:user_id]).to eq "42"
336
- Timecop.travel(Time.now.in_time_zone+0.6)
355
+ expect(session[:user_id]).to eq '42'
356
+ Timecop.travel(Time.now.in_time_zone + 0.6)
337
357
  get :test_should_be_logged_in
338
358
 
339
359
  expect(session[:user_id]).to be_nil
@@ -344,43 +364,52 @@ describe SorceryController, :active_record => true do
344
364
  end
345
365
 
346
366
  def stub_all_oauth2_requests!
347
- access_token = double(OAuth2::AccessToken)
367
+ access_token = double(OAuth2::AccessToken)
348
368
  allow(access_token).to receive(:token_param=)
349
- response = double(OAuth2::Response)
350
- allow(response).to receive(:body) { {
351
- "id"=>"123",
352
- "user_id"=>"123", # Needed for Salesforce
353
- "name"=>"Noam Ben Ari",
354
- "first_name"=>"Noam",
355
- "last_name"=>"Ben Ari",
356
- "link"=>"http://www.facebook.com/nbenari1",
357
- "hometown"=>{"id"=>"110619208966868", "name"=>"Haifa, Israel"},
358
- "location"=>{"id"=>"106906559341067", "name"=>"Pardes Hanah, Hefa, Israel"},
359
- "bio"=>"I'm a new daddy, and enjoying it!",
360
- "gender"=>"male",
361
- "email"=>"nbenari@gmail.com",
362
- "timezone"=>2,
363
- "locale"=>"en_US",
364
- "languages"=>[{"id"=>"108405449189952", "name"=>"Hebrew"}, {"id"=>"106059522759137", "name"=>"English"}, {"id"=>"112624162082677", "name"=>"Russian"}],
365
- "verified"=>true,
366
- "updated_time"=>"2011-02-16T20:59:38+0000",
367
- # response for VK auth
368
- "response"=>[
369
- {
370
- "uid"=>"123",
371
- "first_name"=>"Noam",
372
- "last_name"=>"Ben Ari"
373
- }
374
- ]}.to_json }
369
+ response = double(OAuth2::Response)
370
+ allow(response).to receive(:body) {
371
+ {
372
+ 'id' => '123',
373
+ 'user_id' => '123', # Needed for Salesforce
374
+ 'name' => 'Noam Ben Ari',
375
+ 'first_name' => 'Noam',
376
+ 'last_name' => 'Ben Ari',
377
+ 'link' => 'http://www.facebook.com/nbenari1',
378
+ 'hometown' => { 'id' => '110619208966868', 'name' => 'Haifa, Israel' },
379
+ 'location' => { 'id' => '106906559341067', 'name' => 'Pardes Hanah, Hefa, Israel' },
380
+ 'bio' => "I'm a new daddy, and enjoying it!",
381
+ 'gender' => 'male',
382
+ 'email' => 'nbenari@gmail.com',
383
+ 'timezone' => 2,
384
+ 'locale' => 'en_US',
385
+ 'languages' => [{ 'id' => '108405449189952', 'name' => 'Hebrew' }, { 'id' => '106059522759137', 'name' => 'English' }, { 'id' => '112624162082677', 'name' => 'Russian' }],
386
+ 'verified' => true,
387
+ 'updated_time' => '2011-02-16T20:59:38+0000',
388
+ # response for VK auth
389
+ 'response' => [
390
+ {
391
+ 'uid' => '123',
392
+ 'first_name' => 'Noam',
393
+ 'last_name' => 'Ben Ari'
394
+ }
395
+ ],
396
+ 'user' => {
397
+ 'name' => 'Sonny Whether',
398
+ 'id' => '123',
399
+ 'email' => 'bobby@example.com'
400
+ },
401
+ # response for wechat auth
402
+ 'unionid' => '123',
403
+ }.to_json }
375
404
  allow(access_token).to receive(:get) { response }
376
- allow(access_token).to receive(:token) { "187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3" }
405
+ allow(access_token).to receive(:token) { '187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3' }
377
406
  # access_token params for VK auth
378
- allow(access_token).to receive(:params) { { "user_id"=>"100500", "email"=>"nbenari@gmail.com" } }
407
+ allow(access_token).to receive(:params) { { 'user_id' => '100500', 'email' => 'nbenari@gmail.com' } }
379
408
  allow_any_instance_of(OAuth2::Strategy::AuthCode).to receive(:get_token) { access_token }
380
409
  end
381
410
 
382
411
  def set_external_property
383
- sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce])
412
+ sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat])
384
413
  sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
385
414
  sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
386
415
  sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
@@ -399,16 +428,27 @@ describe SorceryController, :active_record => true do
399
428
  sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w")
400
429
  sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
401
430
  sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com")
431
+ sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w")
432
+ sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
433
+ sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com")
434
+ sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w")
435
+ sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
436
+ sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com")
437
+ sorcery_controller_external_property_set(:wechat, :key, "eYVNBjBDi33aa9GkA3w")
438
+ sorcery_controller_external_property_set(:wechat, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
439
+ sorcery_controller_external_property_set(:wechat, :callback_url, "http://blabla.com")
402
440
  end
403
441
 
404
442
  def provider_url(provider)
405
443
  {
406
- github: "https://github.com/login/oauth/authorize?client_id=#{::Sorcery::Controller::Config.github.key}&display=&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=&state=",
407
- google: "https://accounts.google.com/o/oauth2/auth?client_id=#{::Sorcery::Controller::Config.google.key}&display=&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=",
408
- liveid: "https://oauth.live.com/authorize?client_id=#{::Sorcery::Controller::Config.liveid.key}&display=&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=wl.basic+wl.emails+wl.offline_access&state=",
409
- vk: "https://oauth.vk.com/authorize?client_id=#{::Sorcery::Controller::Config.vk.key}&display=&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.vk.scope}&state=",
410
- salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display=&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.salesforce.scope}&state="
444
+ github: "https://github.com/login/oauth/authorize?client_id=#{::Sorcery::Controller::Config.github.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope&state",
445
+ paypal: "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize?client_id=#{::Sorcery::Controller::Config.paypal.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=openid+email&state",
446
+ google: "https://accounts.google.com/o/oauth2/auth?client_id=#{::Sorcery::Controller::Config.google.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state",
447
+ liveid: "https://oauth.live.com/authorize?client_id=#{::Sorcery::Controller::Config.liveid.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=wl.basic+wl.emails+wl.offline_access&state",
448
+ vk: "https://oauth.vk.com/authorize?client_id=#{::Sorcery::Controller::Config.vk.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.vk.scope}&state",
449
+ salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state",
450
+ slack: "https://slack.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.slack.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identity.basic%2C+identity.email&state",
451
+ wechat: "https://open.weixin.qq.com/connect/qrconnect?appid=#{::Sorcery::Controller::Config.wechat.key}&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=snsapi_login&state=#wechat_redirect"
411
452
  }[provider]
412
453
  end
413
454
  end
414
-