sorcery 0.9.0 → 0.9.1
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/CHANGELOG.md +9 -0
- data/README.md +1 -0
- data/lib/generators/sorcery/templates/initializer.rb +2 -1
- data/lib/generators/sorcery/templates/migration/external.rb +1 -1
- data/lib/sorcery/controller/submodules/external.rb +1 -1
- data/lib/sorcery/model.rb +4 -0
- data/lib/sorcery/providers/facebook.rb +15 -4
- data/lib/sorcery/providers/github.rb +10 -1
- data/lib/sorcery/providers/xing.rb +1 -1
- data/lib/sorcery/version.rb +1 -1
- data/spec/controllers/controller_oauth2_spec.rb +23 -8
- data/spec/shared_examples/user_shared_examples.rb +29 -16
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c0e37f33ed4fa3e085ccc8e3a6a5526afb632f2
|
4
|
+
data.tar.gz: 1b224ad20e8ed01e04a2b7a25153e5949b56fa4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d1dd07a9ab99ade78c490bfffd27144b3951d5ba1f45bcfc1baede6db4cbe228e8916025bfd69fbc48d3342724b00ac2cfd9ecc41110d1b9fdd9559885091b
|
7
|
+
data.tar.gz: 250ceb737b38dab40dd3e16488f3e37aadf2b09fe94c6147ed92a2d42aab2d61d01601b3a2891403f70cc23ef4e675f4fb1ad83072d59ee71d8d6e5fd9d9c20d
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,15 @@
|
|
4
4
|
|
5
5
|
* Adapters (Mongoid, MongoMapper, DataMapper) are now separated from the core Sorcery repo and moved under `sorcery-rails` organization. Special thanks to @juike!
|
6
6
|
|
7
|
+
## 0.9.1
|
8
|
+
|
9
|
+
* Fixed fetching private emails from github (thanks to @saratovsource)
|
10
|
+
* Added support for `active_for_authentication?` method (thanks to @gchaincl)
|
11
|
+
* Fixed migration bug for `external` submodule (thanks to @skv-headless)
|
12
|
+
* Added support for new Facebook Graph API (thanks to @mchaisse)
|
13
|
+
* Fixed issue with Xing submodule (thanks to @yoyostile)
|
14
|
+
* Fixed security bug with using `state` field in oAuth requests
|
15
|
+
|
7
16
|
## 0.9.0
|
8
17
|
|
9
18
|
* Sending emails works with Rails 4.2 (thanks to @wooly)
|
data/README.md
CHANGED
@@ -59,6 +59,7 @@ logged_in? # available to view
|
|
59
59
|
current_user # available to view
|
60
60
|
redirect_back_or_to # used when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted.
|
61
61
|
@user.external? # external users, such as facebook/twitter etc.
|
62
|
+
@user.active_for_authentication? # add this method to define behaviour that will prevent selected users from signing in
|
62
63
|
User.authenticates_with_sorcery!
|
63
64
|
```
|
64
65
|
|
@@ -119,8 +119,9 @@ Rails.application.config.sorcery.configure do |config|
|
|
119
119
|
# config.facebook.secret = ""
|
120
120
|
# config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
|
121
121
|
# config.facebook.user_info_mapping = {:email => "name"}
|
122
|
-
# config.facebook.access_permissions = ["email", "
|
122
|
+
# config.facebook.access_permissions = ["email", "publish_actions"]
|
123
123
|
# config.facebook.display = "page"
|
124
|
+
# config.facebook.api_version = "v2.2"
|
124
125
|
#
|
125
126
|
# config.github.key = ""
|
126
127
|
# config.github.secret = ""
|
@@ -61,7 +61,7 @@ module Sorcery
|
|
61
61
|
@provider = sorcery_get_provider provider_name
|
62
62
|
sorcery_fixup_callback_url @provider
|
63
63
|
if @provider.respond_to?(:login_url) && @provider.has_callback?
|
64
|
-
@provider.state = args[:state]
|
64
|
+
@provider.state = args[:state]
|
65
65
|
return @provider.login_url(params, session)
|
66
66
|
else
|
67
67
|
return nil
|
data/lib/sorcery/model.rb
CHANGED
@@ -92,6 +92,10 @@ module Sorcery
|
|
92
92
|
|
93
93
|
user = sorcery_adapter.find_by_credentials(credentials)
|
94
94
|
|
95
|
+
if user.respond_to?(:active_for_authentication?)
|
96
|
+
return nil if !user.active_for_authentication?
|
97
|
+
end
|
98
|
+
|
95
99
|
set_encryption_attributes
|
96
100
|
|
97
101
|
user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && user.valid_password?(credentials[1])
|
@@ -12,16 +12,18 @@ module Sorcery
|
|
12
12
|
|
13
13
|
attr_reader :mode, :param_name, :parse
|
14
14
|
attr_accessor :access_permissions, :display, :scope, :token_url,
|
15
|
-
:user_info_path
|
15
|
+
:user_info_path, :auth_path, :api_version
|
16
16
|
|
17
17
|
def initialize
|
18
18
|
super
|
19
19
|
|
20
20
|
@site = 'https://graph.facebook.com'
|
21
|
-
@
|
22
|
-
@
|
21
|
+
@auth_site = 'https://www.facebook.com'
|
22
|
+
@user_info_path = 'me'
|
23
|
+
@scope = 'email'
|
23
24
|
@display = 'page'
|
24
25
|
@token_url = 'oauth/access_token'
|
26
|
+
@auth_path = 'dialog/oauth'
|
25
27
|
@mode = :query
|
26
28
|
@parse = :query
|
27
29
|
@param_name = 'access_token'
|
@@ -44,8 +46,17 @@ module Sorcery
|
|
44
46
|
|
45
47
|
# overrides oauth2#authorize_url to allow customized scope.
|
46
48
|
def authorize_url
|
49
|
+
|
50
|
+
# Fix: replace default oauth2 options, specially to prevent the Faraday gem which
|
51
|
+
# concatenates with "/", removing the Facebook api version
|
52
|
+
options = {
|
53
|
+
site: File::join(@site, api_version.to_s),
|
54
|
+
authorize_url: File::join(@auth_site, api_version.to_s, auth_path),
|
55
|
+
token_url: token_url
|
56
|
+
}
|
57
|
+
|
47
58
|
@scope = access_permissions.present? ? access_permissions.join(',') : scope
|
48
|
-
super
|
59
|
+
super(options)
|
49
60
|
end
|
50
61
|
|
51
62
|
# tries to login the user from access token
|
@@ -26,7 +26,9 @@ module Sorcery
|
|
26
26
|
response = access_token.get(user_info_path)
|
27
27
|
|
28
28
|
auth_hash(access_token).tap do |h|
|
29
|
-
h[:user_info] = JSON.parse(response.body)
|
29
|
+
h[:user_info] = JSON.parse(response.body).tap do |uih|
|
30
|
+
uih['email'] = primary_email(access_token) if scope =~ /user/
|
31
|
+
end
|
30
32
|
h[:uid] = h[:user_info]['id']
|
31
33
|
end
|
32
34
|
end
|
@@ -46,6 +48,13 @@ module Sorcery
|
|
46
48
|
get_access_token(args, token_url: token_url, token_method: :post)
|
47
49
|
end
|
48
50
|
|
51
|
+
def primary_email(access_token)
|
52
|
+
response = access_token.get(user_info_path + "/emails")
|
53
|
+
emails = JSON.parse(response.body)
|
54
|
+
primary = emails.find{|i| i['primary'] }
|
55
|
+
primary && primary['email'] || emails.first && emails.first['email']
|
56
|
+
end
|
57
|
+
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
data/lib/sorcery/version.rb
CHANGED
@@ -83,29 +83,44 @@ describe SorceryController, :active_record => true do
|
|
83
83
|
it "login_at redirects correctly" do
|
84
84
|
get :login_at_test_facebook
|
85
85
|
expect(response).to be_a_redirect
|
86
|
-
expect(response).to redirect_to("https://
|
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=")
|
87
87
|
end
|
88
|
+
|
88
89
|
it "logins with state" do
|
89
90
|
get :login_at_test_with_state
|
90
91
|
expect(response).to be_a_redirect
|
91
|
-
expect(response).to redirect_to("https://
|
92
|
+
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
|
+
end
|
94
|
+
|
95
|
+
it "logins with Graph API version" do
|
96
|
+
sorcery_controller_external_property_set(:facebook, :api_version, "v2.2")
|
97
|
+
get :login_at_test_with_state
|
98
|
+
expect(response).to be_a_redirect
|
99
|
+
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
|
+
end
|
101
|
+
|
102
|
+
it "logins without state after login with state" do
|
103
|
+
get :login_at_test_with_state
|
104
|
+
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
|
+
|
106
|
+
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=")
|
92
108
|
end
|
109
|
+
|
93
110
|
after do
|
94
111
|
sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
|
95
112
|
end
|
96
113
|
end
|
97
114
|
|
98
|
-
#this test can never pass because of the previous test (the callback url can't change anymore)
|
99
|
-
=begin
|
100
115
|
context "when callback_url begin with http://" do
|
101
116
|
it "login_at redirects correctly" do
|
102
117
|
create_new_user
|
103
|
-
get :
|
104
|
-
response.
|
105
|
-
response.
|
118
|
+
get :login_at_test_facebook
|
119
|
+
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=")
|
106
121
|
end
|
107
122
|
end
|
108
|
-
|
123
|
+
|
109
124
|
it "'login_from' logins if user exists" do
|
110
125
|
# dirty hack for rails 4
|
111
126
|
allow(subject).to receive(:register_last_activity_time_to_db)
|
@@ -87,29 +87,42 @@ shared_examples_for "rails_3_core_model" do
|
|
87
87
|
expect(User).to respond_to :authenticate
|
88
88
|
end
|
89
89
|
|
90
|
-
|
91
|
-
|
90
|
+
describe "#authenticate" do
|
91
|
+
it "returns user if credentials are good" do
|
92
|
+
expect(User.authenticate user.email, 'secret').to eq user
|
93
|
+
end
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
+
it "returns nil if credentials are bad" do
|
96
|
+
expect(User.authenticate user.email, 'wrong!').to be nil
|
97
|
+
end
|
95
98
|
|
96
|
-
|
97
|
-
|
99
|
+
context "with empty credentials" do
|
100
|
+
before do
|
101
|
+
sorcery_model_property_set(:downcase_username_before_authenticating, true)
|
102
|
+
end
|
98
103
|
|
99
|
-
|
100
|
-
|
104
|
+
after do
|
105
|
+
sorcery_reload!
|
106
|
+
end
|
101
107
|
|
102
|
-
|
103
|
-
|
104
|
-
|
108
|
+
it "don't downcase empty credentials" do
|
109
|
+
expect(User.authenticate(nil, 'wrong!')).to be_falsy
|
110
|
+
end
|
105
111
|
end
|
106
112
|
|
107
|
-
|
108
|
-
|
109
|
-
|
113
|
+
context "and model implements active_for_authentication?" do
|
114
|
+
|
115
|
+
it "authenticates returns user if active_for_authentication? returns true" do
|
116
|
+
allow_any_instance_of(User).to receive(:active_for_authentication?) { true }
|
110
117
|
|
111
|
-
|
112
|
-
|
118
|
+
expect(User.authenticate user.email, 'secret').to eq user
|
119
|
+
end
|
120
|
+
|
121
|
+
it "authenticate returns nil if active_for_authentication? returns false" do
|
122
|
+
allow_any_instance_of(User).to receive(:active_for_authentication?) { false }
|
123
|
+
|
124
|
+
expect(User.authenticate user.email, 'secret').to be_nil
|
125
|
+
end
|
113
126
|
end
|
114
127
|
end
|
115
128
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sorcery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noam Ben Ari
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-04-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: oauth
|
@@ -365,3 +365,4 @@ signing_key:
|
|
365
365
|
specification_version: 4
|
366
366
|
summary: Magical authentication for Rails 3 & 4 applications
|
367
367
|
test_files: []
|
368
|
+
has_rdoc:
|