sorcery 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +29 -104
- data/CHANGELOG.md +13 -1
- data/Gemfile +2 -16
- data/README.md +124 -272
- data/Rakefile +2 -2
- data/gemfiles/{mongoid-rails40.gemfile → active_record-rails42.gemfile} +1 -3
- data/lib/generators/sorcery/helpers.rb +4 -4
- data/lib/generators/sorcery/install_generator.rb +25 -19
- data/lib/generators/sorcery/templates/initializer.rb +27 -52
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +2 -2
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +1 -1
- data/lib/generators/sorcery/templates/migration/core.rb +3 -3
- data/lib/generators/sorcery/templates/migration/external.rb +2 -2
- data/lib/generators/sorcery/templates/migration/remember_me.rb +2 -2
- data/lib/generators/sorcery/templates/migration/reset_password.rb +2 -2
- data/lib/generators/sorcery/templates/migration/user_activation.rb +2 -2
- data/lib/sorcery.rb +0 -28
- data/lib/sorcery/adapters/active_record_adapter.rb +7 -18
- data/lib/sorcery/controller.rb +19 -21
- data/lib/sorcery/controller/config.rb +20 -18
- data/lib/sorcery/controller/submodules/activity_logging.rb +7 -15
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
- data/lib/sorcery/controller/submodules/external.rb +22 -14
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +16 -19
- data/lib/sorcery/controller/submodules/remember_me.rb +15 -10
- data/lib/sorcery/controller/submodules/session_timeout.rb +7 -8
- data/lib/sorcery/crypto_providers/aes256.rb +15 -15
- data/lib/sorcery/crypto_providers/bcrypt.rb +19 -21
- data/lib/sorcery/crypto_providers/common.rb +1 -1
- data/lib/sorcery/crypto_providers/md5.rb +5 -5
- data/lib/sorcery/crypto_providers/sha1.rb +5 -5
- data/lib/sorcery/crypto_providers/sha256.rb +2 -2
- data/lib/sorcery/crypto_providers/sha512.rb +3 -3
- data/lib/sorcery/engine.rb +3 -8
- data/lib/sorcery/model.rb +24 -32
- data/lib/sorcery/model/config.rb +64 -49
- data/lib/sorcery/model/submodules/activity_logging.rb +31 -12
- data/lib/sorcery/model/submodules/brute_force_protection.rb +23 -23
- data/lib/sorcery/model/submodules/external.rb +3 -7
- data/lib/sorcery/model/submodules/remember_me.rb +19 -7
- data/lib/sorcery/model/submodules/reset_password.rb +32 -36
- data/lib/sorcery/model/submodules/user_activation.rb +38 -50
- data/lib/sorcery/model/temporary_token.rb +2 -2
- data/lib/sorcery/protocols/oauth.rb +3 -9
- data/lib/sorcery/protocols/oauth2.rb +0 -2
- data/lib/sorcery/providers/base.rb +4 -4
- data/lib/sorcery/providers/facebook.rb +5 -8
- data/lib/sorcery/providers/github.rb +5 -7
- data/lib/sorcery/providers/google.rb +3 -5
- data/lib/sorcery/providers/heroku.rb +6 -8
- data/lib/sorcery/providers/jira.rb +12 -17
- data/lib/sorcery/providers/linkedin.rb +6 -8
- data/lib/sorcery/providers/liveid.rb +4 -7
- data/lib/sorcery/providers/paypal.rb +60 -0
- data/lib/sorcery/providers/salesforce.rb +3 -5
- data/lib/sorcery/providers/slack.rb +45 -0
- data/lib/sorcery/providers/twitter.rb +4 -6
- data/lib/sorcery/providers/vk.rb +3 -5
- data/lib/sorcery/providers/wechat.rb +79 -0
- data/lib/sorcery/providers/xing.rb +7 -10
- data/lib/sorcery/test_helpers/internal.rb +10 -10
- data/lib/sorcery/test_helpers/internal/rails.rb +16 -8
- data/lib/sorcery/test_helpers/rails/controller.rb +1 -1
- data/lib/sorcery/test_helpers/rails/integration.rb +5 -6
- data/lib/sorcery/version.rb +1 -1
- data/sorcery.gemspec +25 -27
- data/spec/active_record/user_activation_spec.rb +2 -3
- data/spec/active_record/user_activity_logging_spec.rb +2 -4
- data/spec/active_record/user_brute_force_protection_spec.rb +3 -4
- data/spec/active_record/user_oauth_spec.rb +3 -4
- data/spec/active_record/user_remember_me_spec.rb +3 -4
- data/spec/active_record/user_reset_password_spec.rb +2 -3
- data/spec/active_record/user_spec.rb +7 -7
- data/spec/controllers/controller_activity_logging_spec.rb +13 -24
- data/spec/controllers/controller_brute_force_protection_spec.rb +6 -8
- data/spec/controllers/controller_http_basic_auth_spec.rb +19 -20
- data/spec/controllers/controller_oauth2_spec.rb +125 -100
- data/spec/controllers/controller_oauth_spec.rb +86 -66
- data/spec/controllers/controller_remember_me_spec.rb +35 -30
- data/spec/controllers/controller_session_timeout_spec.rb +14 -15
- data/spec/controllers/controller_spec.rb +77 -111
- data/spec/orm/active_record.rb +1 -1
- data/spec/rails_app/app/active_record/authentication.rb +1 -1
- data/spec/rails_app/app/active_record/user.rb +2 -2
- data/spec/rails_app/app/controllers/sorcery_controller.rb +89 -24
- data/spec/rails_app/app/mailers/sorcery_mailer.rb +16 -17
- data/spec/rails_app/config.ru +1 -1
- data/spec/rails_app/config/application.rb +7 -7
- data/spec/rails_app/config/boot.rb +1 -1
- data/spec/rails_app/config/environments/test.rb +1 -1
- data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +11 -0
- data/spec/rails_app/config/initializers/session_store.rb +3 -3
- data/spec/rails_app/config/routes.rb +11 -1
- data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +4 -4
- data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +8 -8
- data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +5 -5
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +5 -5
- data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +3 -3
- data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +6 -6
- data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +5 -5
- data/spec/shared_examples/user_activation_shared_examples.rb +99 -58
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +47 -41
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +19 -24
- data/spec/shared_examples/user_oauth_shared_examples.rb +7 -10
- data/spec/shared_examples/user_remember_me_shared_examples.rb +90 -21
- data/spec/shared_examples/user_reset_password_shared_examples.rb +52 -54
- data/spec/shared_examples/user_shared_examples.rb +215 -118
- data/spec/sorcery_crypto_providers_spec.rb +63 -76
- data/spec/spec_helper.rb +17 -13
- metadata +28 -83
- data/gemfiles/mongo_mapper-rails40.gemfile +0 -9
- data/gemfiles/mongo_mapper-rails41.gemfile +0 -9
- data/gemfiles/mongoid-rails41.gemfile +0 -9
- data/gemfiles/mongoid3-rails32.gemfile +0 -9
- data/lib/sorcery/adapters/data_mapper_adapter.rb +0 -176
- data/lib/sorcery/adapters/mongo_mapper_adapter.rb +0 -110
- data/lib/sorcery/adapters/mongoid_adapter.rb +0 -97
- data/lib/sorcery/railties/tasks.rake +0 -6
- data/spec/data_mapper/user_activation_spec.rb +0 -10
- data/spec/data_mapper/user_activity_logging_spec.rb +0 -14
- data/spec/data_mapper/user_brute_force_protection_spec.rb +0 -9
- data/spec/data_mapper/user_oauth_spec.rb +0 -9
- data/spec/data_mapper/user_remember_me_spec.rb +0 -8
- data/spec/data_mapper/user_reset_password_spec.rb +0 -8
- data/spec/data_mapper/user_spec.rb +0 -27
- data/spec/mongo_mapper/user_activation_spec.rb +0 -9
- data/spec/mongo_mapper/user_activity_logging_spec.rb +0 -8
- data/spec/mongo_mapper/user_brute_force_protection_spec.rb +0 -8
- data/spec/mongo_mapper/user_oauth_spec.rb +0 -8
- data/spec/mongo_mapper/user_remember_me_spec.rb +0 -8
- data/spec/mongo_mapper/user_reset_password_spec.rb +0 -8
- data/spec/mongo_mapper/user_spec.rb +0 -37
- data/spec/mongoid/user_activation_spec.rb +0 -9
- data/spec/mongoid/user_activity_logging_spec.rb +0 -8
- data/spec/mongoid/user_brute_force_protection_spec.rb +0 -8
- data/spec/mongoid/user_oauth_spec.rb +0 -8
- data/spec/mongoid/user_remember_me_spec.rb +0 -8
- data/spec/mongoid/user_reset_password_spec.rb +0 -8
- data/spec/mongoid/user_spec.rb +0 -51
- data/spec/orm/data_mapper.rb +0 -48
- data/spec/orm/mongo_mapper.rb +0 -10
- data/spec/orm/mongoid.rb +0 -22
- data/spec/rails_app/app/data_mapper/authentication.rb +0 -8
- data/spec/rails_app/app/data_mapper/user.rb +0 -7
- data/spec/rails_app/app/mongo_mapper/authentication.rb +0 -6
- data/spec/rails_app/app/mongo_mapper/user.rb +0 -7
- data/spec/rails_app/app/mongoid/authentication.rb +0 -7
- data/spec/rails_app/app/mongoid/user.rb +0 -7
@@ -1,68 +1,67 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe SorceryController do
|
3
|
+
describe SorceryController, type: :controller do
|
4
|
+
let(:user) { double('user', id: 42, email: 'bla@bla.com') }
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
describe "with http basic auth features" do
|
6
|
+
describe 'with http basic auth features' do
|
8
7
|
before(:all) do
|
9
8
|
sorcery_reload!([:http_basic_auth])
|
10
9
|
|
11
|
-
sorcery_controller_property_set(:controller_to_realm_map,
|
10
|
+
sorcery_controller_property_set(:controller_to_realm_map, 'sorcery' => 'sorcery')
|
12
11
|
end
|
13
12
|
|
14
13
|
after(:each) do
|
15
14
|
logout_user
|
16
15
|
end
|
17
16
|
|
18
|
-
it
|
17
|
+
it 'requests basic authentication when before_action is used' do
|
19
18
|
get :test_http_basic_auth
|
20
19
|
|
21
20
|
expect(response.status).to eq 401
|
22
21
|
end
|
23
22
|
|
24
|
-
it
|
23
|
+
it 'authenticates from http basic if credentials are sent' do
|
25
24
|
# dirty hack for rails 4
|
26
25
|
allow(subject).to receive(:register_last_activity_time_to_db)
|
27
26
|
|
28
|
-
@request.env[
|
27
|
+
@request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:secret")}"
|
29
28
|
expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user)
|
30
|
-
get :test_http_basic_auth,
|
29
|
+
get :test_http_basic_auth, params: {}, session: { http_authentication_used: true }
|
31
30
|
|
32
31
|
expect(response).to be_a_success
|
33
32
|
end
|
34
33
|
|
35
|
-
it
|
36
|
-
@request.env[
|
34
|
+
it 'fails authentication if credentials are wrong' do
|
35
|
+
@request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:wrong!")}"
|
37
36
|
expect(User).to receive('authenticate').with('bla@bla.com', 'wrong!').and_return(nil)
|
38
|
-
get :test_http_basic_auth,
|
37
|
+
get :test_http_basic_auth, params: {}, session: { http_authentication_used: true }
|
39
38
|
|
40
39
|
expect(response).to redirect_to root_url
|
41
40
|
end
|
42
41
|
|
43
42
|
it "allows configuration option 'controller_to_realm_map'" do
|
44
|
-
sorcery_controller_property_set(:controller_to_realm_map,
|
43
|
+
sorcery_controller_property_set(:controller_to_realm_map, '1' => '2')
|
45
44
|
|
46
|
-
expect(Sorcery::Controller::Config.controller_to_realm_map).to eq(
|
45
|
+
expect(Sorcery::Controller::Config.controller_to_realm_map).to eq('1' => '2')
|
47
46
|
end
|
48
47
|
|
49
|
-
it
|
50
|
-
sorcery_controller_property_set(:controller_to_realm_map,
|
48
|
+
it 'displays the correct realm name configured for the controller' do
|
49
|
+
sorcery_controller_property_set(:controller_to_realm_map, 'sorcery' => 'Salad')
|
51
50
|
get :test_http_basic_auth
|
52
51
|
|
53
|
-
expect(response.headers[
|
52
|
+
expect(response.headers['WWW-Authenticate']).to eq 'Basic realm="Salad"'
|
54
53
|
end
|
55
54
|
|
56
55
|
it "signs in the user's session on successful login" do
|
57
56
|
# dirty hack for rails 4
|
58
57
|
allow(controller).to receive(:register_last_activity_time_to_db)
|
59
58
|
|
60
|
-
@request.env[
|
59
|
+
@request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:secret")}"
|
61
60
|
expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user)
|
62
61
|
|
63
|
-
get :test_http_basic_auth,
|
62
|
+
get :test_http_basic_auth, params: {}, session: { http_authentication_used: true }
|
64
63
|
|
65
|
-
expect(session[:user_id]).to eq
|
64
|
+
expect(session[:user_id]).to eq '42'
|
66
65
|
end
|
67
66
|
end
|
68
67
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
# require 'shared_examples/controller_oauth2_shared_examples'
|
4
4
|
|
5
|
-
describe SorceryController, :
|
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,
|
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',
|
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,
|
38
|
-
expect(User).to receive(:create_from_provider).with('facebook', '123',
|
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,
|
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',
|
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,
|
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',
|
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
|
67
|
-
|
66
|
+
context 'with OAuth features' do
|
68
67
|
let(:user) { double('user', id: 42) }
|
69
68
|
|
70
69
|
before(:each) do
|
@@ -76,48 +75,48 @@ describe SorceryController, :active_record => true do
|
|
76
75
|
Authentication.sorcery_adapter.delete_all
|
77
76
|
end
|
78
77
|
|
79
|
-
context
|
78
|
+
context 'when callback_url begin with /' do
|
80
79
|
before do
|
81
|
-
sorcery_controller_external_property_set(:facebook, :callback_url,
|
80
|
+
sorcery_controller_external_property_set(:facebook, :callback_url, '/oauth/twitter/callback')
|
82
81
|
end
|
83
|
-
it
|
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://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
|
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")
|
87
86
|
end
|
88
87
|
|
89
|
-
it
|
88
|
+
it 'logins with state' do
|
90
89
|
get :login_at_test_with_state
|
91
90
|
expect(response).to be_a_redirect
|
92
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")
|
93
92
|
end
|
94
93
|
|
95
|
-
it
|
96
|
-
sorcery_controller_external_property_set(:facebook, :api_version,
|
94
|
+
it 'logins with Graph API version' do
|
95
|
+
sorcery_controller_external_property_set(:facebook, :api_version, 'v2.2')
|
97
96
|
get :login_at_test_with_state
|
98
97
|
expect(response).to be_a_redirect
|
99
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")
|
100
99
|
end
|
101
100
|
|
102
|
-
it
|
101
|
+
it 'logins without state after login with state' do
|
103
102
|
get :login_at_test_with_state
|
104
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")
|
105
104
|
|
106
105
|
get :login_at_test_facebook
|
107
|
-
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
|
+
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")
|
108
107
|
end
|
109
108
|
|
110
109
|
after do
|
111
|
-
sorcery_controller_external_property_set(:facebook, :callback_url,
|
110
|
+
sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com')
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
context
|
116
|
-
it
|
114
|
+
context 'when callback_url begin with http://' do
|
115
|
+
it 'login_at redirects correctly' do
|
117
116
|
create_new_user
|
118
117
|
get :login_at_test_facebook
|
119
118
|
expect(response).to be_a_redirect
|
120
|
-
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
|
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")
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
@@ -129,7 +128,7 @@ describe SorceryController, :active_record => true do
|
|
129
128
|
expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user)
|
130
129
|
get :test_login_from_facebook
|
131
130
|
|
132
|
-
expect(flash[:notice]).to eq
|
131
|
+
expect(flash[:notice]).to eq 'Success!'
|
133
132
|
end
|
134
133
|
|
135
134
|
it "'login_from' fails if user doesn't exist" do
|
@@ -137,30 +136,28 @@ describe SorceryController, :active_record => true do
|
|
137
136
|
expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(nil)
|
138
137
|
get :test_login_from_facebook
|
139
138
|
|
140
|
-
expect(flash[:alert]).to eq
|
139
|
+
expect(flash[:alert]).to eq 'Failed!'
|
141
140
|
end
|
142
141
|
|
143
|
-
it
|
142
|
+
it 'on successful login_from the user is redirected to the url he originally wanted' do
|
144
143
|
# dirty hack for rails 4
|
145
144
|
allow(subject).to receive(:register_last_activity_time_to_db)
|
146
145
|
|
147
146
|
sorcery_model_property_set(:authentications_class, Authentication)
|
148
147
|
expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user)
|
149
|
-
get :test_return_to_with_external_facebook, {}, :return_to_url
|
148
|
+
get :test_return_to_with_external_facebook, params: {}, session: { return_to_url: 'fuu' }
|
150
149
|
|
151
|
-
expect(response).to redirect_to(
|
152
|
-
expect(flash[:notice]).to eq
|
150
|
+
expect(response).to redirect_to('fuu')
|
151
|
+
expect(flash[:notice]).to eq 'Success!'
|
153
152
|
end
|
154
153
|
|
155
|
-
[:github, :google, :liveid, :vk, :salesforce].each do |provider|
|
156
|
-
|
154
|
+
[:github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat].each do |provider|
|
157
155
|
describe "with #{provider}" do
|
158
|
-
|
159
|
-
it "login_at redirects correctly" do
|
156
|
+
it 'login_at redirects correctly' do
|
160
157
|
get :"login_at_test_#{provider}"
|
161
158
|
|
162
159
|
expect(response).to be_a_redirect
|
163
|
-
expect(response).to redirect_to(provider_url
|
160
|
+
expect(response).to redirect_to(provider_url(provider))
|
164
161
|
end
|
165
162
|
|
166
163
|
it "'login_from' logins if user exists" do
|
@@ -171,7 +168,7 @@ describe SorceryController, :active_record => true do
|
|
171
168
|
expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user)
|
172
169
|
get :"test_login_from_#{provider}"
|
173
170
|
|
174
|
-
expect(flash[:notice]).to eq
|
171
|
+
expect(flash[:notice]).to eq 'Success!'
|
175
172
|
end
|
176
173
|
|
177
174
|
it "'login_from' fails if user doesn't exist" do
|
@@ -179,7 +176,7 @@ describe SorceryController, :active_record => true do
|
|
179
176
|
expect(User).to receive(:load_from_provider).with(provider, '123').and_return(nil)
|
180
177
|
get :"test_login_from_#{provider}"
|
181
178
|
|
182
|
-
expect(flash[:alert]).to eq
|
179
|
+
expect(flash[:alert]).to eq 'Failed!'
|
183
180
|
end
|
184
181
|
|
185
182
|
it "on successful login_from the user is redirected to the url he originally wanted (#{provider})" do
|
@@ -188,25 +185,25 @@ describe SorceryController, :active_record => true do
|
|
188
185
|
|
189
186
|
sorcery_model_property_set(:authentications_class, Authentication)
|
190
187
|
expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user)
|
191
|
-
get :"test_return_to_with_external_#{provider}", {}, :return_to_url
|
188
|
+
get :"test_return_to_with_external_#{provider}", params: {}, session: { return_to_url: 'fuu' }
|
192
189
|
|
193
|
-
expect(response).to redirect_to
|
194
|
-
expect(flash[:notice]).to eq
|
190
|
+
expect(response).to redirect_to 'fuu'
|
191
|
+
expect(flash[:notice]).to eq 'Success!'
|
195
192
|
end
|
196
193
|
end
|
197
194
|
end
|
198
|
-
|
199
195
|
end
|
200
196
|
|
201
|
-
describe
|
197
|
+
describe 'OAuth with User Activation features' do
|
202
198
|
before(:all) do
|
203
199
|
if SORCERY_ORM == :active_record
|
204
200
|
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
|
205
201
|
end
|
206
202
|
|
207
203
|
sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
|
208
|
-
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])
|
209
205
|
|
206
|
+
# TODO: refactor
|
210
207
|
sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
|
211
208
|
sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
|
212
209
|
sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
|
@@ -225,10 +222,20 @@ describe SorceryController, :active_record => true do
|
|
225
222
|
sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w")
|
226
223
|
sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
|
227
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")
|
228
234
|
end
|
229
235
|
|
230
236
|
after(:all) do
|
231
237
|
if SORCERY_ORM == :active_record
|
238
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
232
239
|
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
233
240
|
end
|
234
241
|
end
|
@@ -237,14 +244,14 @@ describe SorceryController, :active_record => true do
|
|
237
244
|
User.sorcery_adapter.delete_all
|
238
245
|
end
|
239
246
|
|
240
|
-
it
|
247
|
+
it 'does not send activation email to external users' do
|
241
248
|
old_size = ActionMailer::Base.deliveries.size
|
242
249
|
create_new_external_user(:facebook)
|
243
250
|
|
244
251
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
245
252
|
end
|
246
253
|
|
247
|
-
it
|
254
|
+
it 'does not send external users an activation success email' do
|
248
255
|
sorcery_model_property_set(:activation_success_email_method_name, nil)
|
249
256
|
create_new_external_user(:facebook)
|
250
257
|
old_size = ActionMailer::Base.deliveries.size
|
@@ -253,7 +260,7 @@ describe SorceryController, :active_record => true do
|
|
253
260
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
254
261
|
end
|
255
262
|
|
256
|
-
[:github, :google, :liveid, :vk, :salesforce].each do |provider|
|
263
|
+
[:github, :google, :liveid, :vk, :salesforce, :paypal, :wechat].each do |provider|
|
257
264
|
it "does not send activation email to external users (#{provider})" do
|
258
265
|
old_size = ActionMailer::Base.deliveries.size
|
259
266
|
create_new_external_user provider
|
@@ -269,8 +276,7 @@ describe SorceryController, :active_record => true do
|
|
269
276
|
end
|
270
277
|
end
|
271
278
|
|
272
|
-
describe
|
273
|
-
|
279
|
+
describe 'OAuth with user activation features' do
|
274
280
|
let(:user) { double('user', id: 42) }
|
275
281
|
|
276
282
|
before(:all) do
|
@@ -284,7 +290,7 @@ describe SorceryController, :active_record => true do
|
|
284
290
|
end
|
285
291
|
end
|
286
292
|
|
287
|
-
%w(facebook github google liveid vk salesforce).each do |provider|
|
293
|
+
%w(facebook github google liveid vk salesforce slack).each do |provider|
|
288
294
|
context "when #{provider}" do
|
289
295
|
before(:each) do
|
290
296
|
sorcery_controller_property_set(:register_login_time, true)
|
@@ -295,7 +301,7 @@ describe SorceryController, :active_record => true do
|
|
295
301
|
sorcery_model_property_set(:authentications_class, Authentication)
|
296
302
|
end
|
297
303
|
|
298
|
-
it
|
304
|
+
it 'registers login time' do
|
299
305
|
now = Time.now.in_time_zone
|
300
306
|
Timecop.freeze(now)
|
301
307
|
expect(User).to receive(:load_from_provider).and_return(user)
|
@@ -304,31 +310,30 @@ describe SorceryController, :active_record => true do
|
|
304
310
|
Timecop.return
|
305
311
|
end
|
306
312
|
|
307
|
-
it
|
313
|
+
it 'does not register login time if configured so' do
|
308
314
|
sorcery_controller_property_set(:register_login_time, false)
|
309
315
|
now = Time.now.in_time_zone
|
310
316
|
Timecop.freeze(now)
|
311
317
|
expect(User).to receive(:load_from_provider).and_return(user)
|
312
318
|
expect(user).to receive(:set_last_login_at).never
|
313
319
|
get "test_login_from_#{provider}".to_sym
|
314
|
-
|
315
320
|
end
|
316
321
|
end
|
317
322
|
end
|
318
323
|
end
|
319
324
|
|
320
|
-
describe
|
325
|
+
describe 'OAuth with session timeout features' do
|
321
326
|
before(:all) do
|
322
327
|
sorcery_reload!([:session_timeout, :external])
|
323
328
|
end
|
324
329
|
|
325
330
|
let(:user) { double('user', id: 42) }
|
326
331
|
|
327
|
-
%w(facebook github google liveid vk salesforce).each do |provider|
|
332
|
+
%w(facebook github google liveid vk salesforce slack).each do |provider|
|
328
333
|
context "when #{provider}" do
|
329
334
|
before(:each) do
|
330
335
|
sorcery_model_property_set(:authentications_class, Authentication)
|
331
|
-
sorcery_controller_property_set(:session_timeout,0.5)
|
336
|
+
sorcery_controller_property_set(:session_timeout, 0.5)
|
332
337
|
stub_all_oauth2_requests!
|
333
338
|
end
|
334
339
|
|
@@ -336,19 +341,19 @@ describe SorceryController, :active_record => true do
|
|
336
341
|
Timecop.return
|
337
342
|
end
|
338
343
|
|
339
|
-
it
|
344
|
+
it 'does not reset session before session timeout' do
|
340
345
|
expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user)
|
341
346
|
get "test_login_from_#{provider}".to_sym
|
342
347
|
|
343
348
|
expect(session[:user_id]).not_to be_nil
|
344
|
-
expect(flash[:notice]).to eq
|
349
|
+
expect(flash[:notice]).to eq 'Success!'
|
345
350
|
end
|
346
351
|
|
347
|
-
it
|
352
|
+
it 'resets session after session timeout' do
|
348
353
|
expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user)
|
349
354
|
get "test_login_from_#{provider}".to_sym
|
350
|
-
expect(session[:user_id]).to eq
|
351
|
-
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)
|
352
357
|
get :test_should_be_logged_in
|
353
358
|
|
354
359
|
expect(session[:user_id]).to be_nil
|
@@ -359,43 +364,52 @@ describe SorceryController, :active_record => true do
|
|
359
364
|
end
|
360
365
|
|
361
366
|
def stub_all_oauth2_requests!
|
362
|
-
access_token
|
367
|
+
access_token = double(OAuth2::AccessToken)
|
363
368
|
allow(access_token).to receive(:token_param=)
|
364
|
-
response
|
365
|
-
allow(response).to receive(:body) {
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
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 }
|
390
404
|
allow(access_token).to receive(:get) { response }
|
391
|
-
allow(access_token).to receive(:token) {
|
405
|
+
allow(access_token).to receive(:token) { '187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3' }
|
392
406
|
# access_token params for VK auth
|
393
|
-
allow(access_token).to receive(:params) { {
|
407
|
+
allow(access_token).to receive(:params) { { 'user_id' => '100500', 'email' => 'nbenari@gmail.com' } }
|
394
408
|
allow_any_instance_of(OAuth2::Strategy::AuthCode).to receive(:get_token) { access_token }
|
395
409
|
end
|
396
410
|
|
397
411
|
def set_external_property
|
398
|
-
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])
|
399
413
|
sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
|
400
414
|
sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
|
401
415
|
sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
|
@@ -414,16 +428,27 @@ describe SorceryController, :active_record => true do
|
|
414
428
|
sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w")
|
415
429
|
sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
|
416
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")
|
417
440
|
end
|
418
441
|
|
419
442
|
def provider_url(provider)
|
420
443
|
{
|
421
|
-
github: "https://github.com/login/oauth/authorize?client_id=#{::Sorcery::Controller::Config.github.key}&display
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
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"
|
426
452
|
}[provider]
|
427
453
|
end
|
428
454
|
end
|
429
|
-
|