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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f79fec92f71b24d1507e3848c0c943e3b8e7a6ed
4
- data.tar.gz: bf2cfc0eb30778fbb3eb85f896a9b73811a179c4
3
+ metadata.gz: 5c0e37f33ed4fa3e085ccc8e3a6a5526afb632f2
4
+ data.tar.gz: 1b224ad20e8ed01e04a2b7a25153e5949b56fa4f
5
5
  SHA512:
6
- metadata.gz: d48170391dc1db75bb8bc88ce444ecc8d957796e0aaf96c29cafc4a01493689bc52e47ecaa5c0968c3aced147d623d2623f9dbe56e3dfdf46bf5309b005345f6
7
- data.tar.gz: 4101544b567f3cb86c02bda20721a864b9c32fb688d62e64e7eee7fc0672614d06e0d8c004c8fa494113a9c834c1a09df1be91454ee00ee58865fcd31d01d7e0
6
+ metadata.gz: 48d1dd07a9ab99ade78c490bfffd27144b3951d5ba1f45bcfc1baede6db4cbe228e8916025bfd69fbc48d3342724b00ac2cfd9ecc41110d1b9fdd9559885091b
7
+ data.tar.gz: 250ceb737b38dab40dd3e16488f3e37aadf2b09fe94c6147ed92a2d42aab2d61d01601b3a2891403f70cc23ef4e675f4fb1ad83072d59ee71d8d6e5fd9d9c20d
@@ -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", "publish_stream"]
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 = ""
@@ -7,6 +7,6 @@ class SorceryExternal < ActiveRecord::Migration
7
7
  t.timestamps
8
8
  end
9
9
 
10
- add_index :<%= model_class_name.tableize %>, [:provider, :uid]
10
+ add_index :authentications, [:provider, :uid]
11
11
  end
12
12
  end
@@ -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] if args[:state]
64
+ @provider.state = args[:state]
65
65
  return @provider.login_url(params, session)
66
66
  else
67
67
  return nil
@@ -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
- @user_info_path = '/me'
22
- @scope = 'email,offline_access'
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
@@ -34,7 +34,7 @@ module Sorcery
34
34
 
35
35
  auth_hash(access_token).tap do |h|
36
36
  h[:user_info] = JSON.parse(response.body)['users'].first
37
- h[:uid] = user_hash[:user_info]['id'].to_s
37
+ h[:uid] = h[:user_info]['id'].to_s
38
38
  end
39
39
  end
40
40
 
@@ -1,3 +1,3 @@
1
1
  module Sorcery
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
@@ -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://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=")
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://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")
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 :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")
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
- =end
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
- it "authenticate returns true if credentials are good" do
91
- username = user.send(User.sorcery_config.username_attribute_names.first)
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
- expect(User.authenticate username, 'secret').to be_truthy
94
- end
95
+ it "returns nil if credentials are bad" do
96
+ expect(User.authenticate user.email, 'wrong!').to be nil
97
+ end
95
98
 
96
- it "authenticate returns nil if credentials are bad" do
97
- username = user.send(User.sorcery_config.username_attribute_names.first)
99
+ context "with empty credentials" do
100
+ before do
101
+ sorcery_model_property_set(:downcase_username_before_authenticating, true)
102
+ end
98
103
 
99
- expect(User.authenticate username, 'wrong!').to be nil
100
- end
104
+ after do
105
+ sorcery_reload!
106
+ end
101
107
 
102
- context "with empty credentials" do
103
- before do
104
- sorcery_model_property_set(:downcase_username_before_authenticating, true)
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
- after do
108
- sorcery_reload!
109
- end
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
- it "don't downcase empty credentials" do
112
- expect(User.authenticate(nil, 'wrong!')).to be_falsy
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.0
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-01-13 00:00:00.000000000 Z
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: