sorcery 0.7.13 → 0.8.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +10 -6
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/generators/sorcery/templates/initializer.rb +19 -0
- data/lib/sorcery.rb +3 -1
- data/lib/sorcery/controller.rb +6 -3
- data/lib/sorcery/controller/submodules/external.rb +1 -1
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +9 -2
- data/lib/sorcery/controller/submodules/external/providers/github.rb +2 -0
- data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +101 -0
- data/lib/sorcery/controller/submodules/external/providers/vkontakte.rb +94 -0
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
- data/lib/sorcery/controller/submodules/remember_me.rb +11 -2
- data/lib/sorcery/model.rb +40 -39
- data/sorcery.gemspec +7 -5
- data/spec/Gemfile +1 -1
- data/spec/Gemfile.lock +10 -6
- data/spec/rails3/Gemfile.lock +10 -6
- data/spec/rails3_mongo_mapper/Gemfile.lock +10 -6
- data/spec/rails3_mongoid/Gemfile.lock +10 -6
- metadata +5 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -46,12 +46,12 @@ GEM
|
|
46
46
|
columnize (0.3.6)
|
47
47
|
diff-lcs (1.1.3)
|
48
48
|
erubis (2.7.0)
|
49
|
-
faraday (0.8.
|
49
|
+
faraday (0.8.4)
|
50
50
|
multipart-post (~> 1.1)
|
51
51
|
ffi (1.0.11)
|
52
52
|
git (1.2.5)
|
53
53
|
hike (1.2.1)
|
54
|
-
httpauth (0.
|
54
|
+
httpauth (0.2.0)
|
55
55
|
i18n (0.6.0)
|
56
56
|
jeweler (1.8.3)
|
57
57
|
bundler (~> 1.0)
|
@@ -60,6 +60,8 @@ GEM
|
|
60
60
|
rdoc
|
61
61
|
journey (1.0.3)
|
62
62
|
json (1.6.6)
|
63
|
+
jwt (0.1.5)
|
64
|
+
multi_json (>= 1.0)
|
63
65
|
linecache19 (0.5.12)
|
64
66
|
ruby_core_source (>= 0.1.4)
|
65
67
|
mail (2.4.4)
|
@@ -81,10 +83,12 @@ GEM
|
|
81
83
|
multipart-post (1.1.5)
|
82
84
|
nokogiri (1.5.2)
|
83
85
|
oauth (0.4.5)
|
84
|
-
oauth2 (0.
|
85
|
-
faraday (~> 0.
|
86
|
+
oauth2 (0.8.0)
|
87
|
+
faraday (~> 0.8)
|
86
88
|
httpauth (~> 0.1)
|
87
|
-
|
89
|
+
jwt (~> 0.1.4)
|
90
|
+
multi_json (~> 1.0)
|
91
|
+
rack (~> 1.2)
|
88
92
|
plucky (0.4.4)
|
89
93
|
mongo (~> 1.5)
|
90
94
|
polyglot (0.3.3)
|
@@ -177,7 +181,7 @@ DEPENDENCIES
|
|
177
181
|
mongo_mapper
|
178
182
|
mongoid (~> 2.4.4)
|
179
183
|
oauth (~> 0.4.4)
|
180
|
-
oauth2 (~> 0.
|
184
|
+
oauth2 (~> 0.8.0)
|
181
185
|
rails (>= 3.0.0)
|
182
186
|
rspec (~> 2.5.0)
|
183
187
|
rspec-rails (~> 2.5.0)
|
data/README.rdoc
CHANGED
@@ -29,7 +29,7 @@ Railscast: http://railscasts.com/episodes/283-authentication-with-sorcery
|
|
29
29
|
|
30
30
|
Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
|
31
31
|
|
32
|
-
Documentation: http://rubydoc.info/gems/sorcery/0.
|
32
|
+
Documentation: http://rubydoc.info/gems/sorcery/0.8.0/frames
|
33
33
|
|
34
34
|
Check out the tutorials in the github wiki!
|
35
35
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
@@ -26,6 +26,13 @@ Rails.application.config.sorcery.configure do |config|
|
|
26
26
|
#
|
27
27
|
# config.cookie_domain =
|
28
28
|
|
29
|
+
|
30
|
+
# -- remember_me --
|
31
|
+
# allow the remember_me cookie to settable through AJAX
|
32
|
+
# Default: `true`
|
33
|
+
#
|
34
|
+
# user.remember_me_httponly =
|
35
|
+
|
29
36
|
|
30
37
|
# -- session timeout --
|
31
38
|
# How long in seconds to keep the session alive.
|
@@ -80,6 +87,17 @@ Rails.application.config.sorcery.configure do |config|
|
|
80
87
|
# config.ca_file =
|
81
88
|
|
82
89
|
|
90
|
+
# For information about LinkedIn API:
|
91
|
+
# - user info fields go to https://developer.linkedin.com/documents/profile-fields
|
92
|
+
# - access permissions go to https://developer.linkedin.com/documents/authentication#granting
|
93
|
+
#
|
94
|
+
# config.linkedin.key = ""
|
95
|
+
# config.linkedin.secret = ""
|
96
|
+
# config.linkedin.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=linkedin"
|
97
|
+
# config.linkedin.user_info_fields = ['first-name', 'last-name']
|
98
|
+
# config.linkedin.user_info_mapping = {first_name: "firstName", last_name: "lastName"}
|
99
|
+
# config.linkedin.access_permissions = ['r_basicprofile']
|
100
|
+
#
|
83
101
|
# Twitter wil not accept any requests nor redirect uri containing localhost,
|
84
102
|
# make sure you use 0.0.0.0:3000 to access your app in development
|
85
103
|
#
|
@@ -92,6 +110,7 @@ Rails.application.config.sorcery.configure do |config|
|
|
92
110
|
# config.facebook.secret = ""
|
93
111
|
# config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
|
94
112
|
# config.facebook.user_info_mapping = {:email => "name"}
|
113
|
+
# config.facebook.access_permissions = ["email", "publish_stream"]
|
95
114
|
#
|
96
115
|
# config.github.key = ""
|
97
116
|
# config.github.secret = ""
|
data/lib/sorcery.rb
CHANGED
@@ -36,6 +36,8 @@ module Sorcery
|
|
36
36
|
autoload :Github, 'sorcery/controller/submodules/external/providers/github'
|
37
37
|
autoload :Google, 'sorcery/controller/submodules/external/providers/google'
|
38
38
|
autoload :Liveid, 'sorcery/controller/submodules/external/providers/liveid'
|
39
|
+
autoload :Linkedin, 'sorcery/controller/submodules/external/providers/linkedin'
|
40
|
+
autoload :Vkontakte, 'sorcery/controller/submodules/external/providers/vkontakte'
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -78,5 +80,5 @@ module Sorcery
|
|
78
80
|
MongoMapper::Document.send(:plugin, Sorcery::Model::Adapters::MongoMapper)
|
79
81
|
end
|
80
82
|
|
81
|
-
require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR
|
83
|
+
require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
82
84
|
end
|
data/lib/sorcery/controller.rb
CHANGED
@@ -28,13 +28,15 @@ module Sorcery
|
|
28
28
|
|
29
29
|
# Takes credentials and returns a user on successful authentication.
|
30
30
|
# Runs hooks after login or failed login.
|
31
|
-
|
31
|
+
def login(*credentials)
|
32
32
|
@current_user = nil
|
33
33
|
user = user_class.authenticate(*credentials)
|
34
34
|
if user
|
35
|
-
|
35
|
+
old_session = session.dup
|
36
36
|
reset_session # protect from session fixation attacks
|
37
|
-
|
37
|
+
old_session.to_hash.each_pair do |k,v|
|
38
|
+
session[k.to_sym] = v
|
39
|
+
end
|
38
40
|
auto_login(user)
|
39
41
|
after_login!(user, credentials)
|
40
42
|
current_user
|
@@ -113,6 +115,7 @@ module Sorcery
|
|
113
115
|
@current_user = (user_class.find(session[:user_id]) if session[:user_id]) || false
|
114
116
|
rescue => exception
|
115
117
|
return false if defined?(Mongoid) and exception.is_a?(Mongoid::Errors::DocumentNotFound)
|
118
|
+
return false if defined?(ActiveRecord) and exception.is_a?(ActiveRecord::RecordNotFound)
|
116
119
|
raise exception
|
117
120
|
end
|
118
121
|
|
@@ -78,7 +78,7 @@ module Sorcery
|
|
78
78
|
config = user_class.sorcery_config
|
79
79
|
|
80
80
|
# first check to see if user has a particular authentication already
|
81
|
-
unless (current_user.send(config.authentications_class.to_s.downcase.pluralize).send("find_by_#{config.provider_attribute_name}_and_#{config.provider_uid_attribute_name}", provider, @user_hash[:uid]))
|
81
|
+
unless (current_user.send(config.authentications_class.to_s.downcase.pluralize).send("find_by_#{config.provider_attribute_name}_and_#{config.provider_uid_attribute_name}", provider, @user_hash[:uid].to_s))
|
82
82
|
user = current_user.send(config.authentications_class.to_s.downcase.pluralize).build(config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name.to_s)
|
83
83
|
user.save(:validate => false)
|
84
84
|
else
|
@@ -35,7 +35,8 @@ module Sorcery
|
|
35
35
|
:user_info_path,
|
36
36
|
:scope,
|
37
37
|
:user_info_mapping,
|
38
|
-
:display
|
38
|
+
:display,
|
39
|
+
:access_permissions
|
39
40
|
attr_reader :access_token
|
40
41
|
|
41
42
|
include Protocols::Oauth2
|
@@ -69,7 +70,13 @@ module Sorcery
|
|
69
70
|
def login_url(params,session)
|
70
71
|
self.authorize_url
|
71
72
|
end
|
72
|
-
|
73
|
+
|
74
|
+
# overrides oauth2#authorize_url to allow customized scope.
|
75
|
+
def authorize_url
|
76
|
+
@scope = self.access_permissions.present? ? self.access_permissions.join(",") : @scope
|
77
|
+
super
|
78
|
+
end
|
79
|
+
|
73
80
|
# tries to login the user from access token
|
74
81
|
def process_callback(params,session)
|
75
82
|
args = {}
|
@@ -34,6 +34,7 @@ module Sorcery
|
|
34
34
|
:auth_path,
|
35
35
|
:token_path,
|
36
36
|
:site,
|
37
|
+
:scope,
|
37
38
|
:user_info_path,
|
38
39
|
:user_info_mapping
|
39
40
|
attr_reader :access_token
|
@@ -43,6 +44,7 @@ module Sorcery
|
|
43
44
|
def init
|
44
45
|
@site = "https://github.com/"
|
45
46
|
@user_info_path = "https://api.github.com/user"
|
47
|
+
@scope = nil
|
46
48
|
@auth_path = "/login/oauth/authorize"
|
47
49
|
@token_path = "/login/oauth/access_token"
|
48
50
|
@user_info_mapping = {}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module Controller
|
3
|
+
module Submodules
|
4
|
+
module External
|
5
|
+
module Providers
|
6
|
+
# This module adds support for OAuth with Linkedin.com.
|
7
|
+
# When included in the 'config.providers' option, it adds a new option, 'config.linkedin'.
|
8
|
+
# Via this new option you can configure Linkedin specific settings like your app's key and secret.
|
9
|
+
#
|
10
|
+
# config.linkedin.key = <key>
|
11
|
+
# config.linkedin.secret = <secret>
|
12
|
+
# ...
|
13
|
+
#
|
14
|
+
module Linkedin
|
15
|
+
def self.included(base)
|
16
|
+
base.module_eval do
|
17
|
+
class << self
|
18
|
+
attr_reader :linkedin
|
19
|
+
|
20
|
+
def merge_linkedin_defaults!
|
21
|
+
@defaults.merge!(:@linkedin => LinkedinClient)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
merge_linkedin_defaults!
|
25
|
+
update!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module LinkedinClient
|
30
|
+
class << self
|
31
|
+
attr_accessor :key,
|
32
|
+
:secret,
|
33
|
+
:callback_url,
|
34
|
+
:site,
|
35
|
+
:authorize_path,
|
36
|
+
:request_token_path,
|
37
|
+
:access_token_path,
|
38
|
+
:user_info_path,
|
39
|
+
:user_info_mapping,
|
40
|
+
:user_info_fields,
|
41
|
+
:access_permissions
|
42
|
+
attr_reader :access_token
|
43
|
+
|
44
|
+
include Protocols::Oauth1
|
45
|
+
|
46
|
+
# Override included get_consumer method to provide authorize_path
|
47
|
+
def get_consumer
|
48
|
+
# Add access permissions to request token path
|
49
|
+
@configuration[:request_token_path] += "?scope=" + self.access_permissions.join('+') unless self.access_permissions.blank? or @configuration[:request_token_path].include? "?scope="
|
50
|
+
::OAuth::Consumer.new(@key, @secret, @configuration)
|
51
|
+
end
|
52
|
+
|
53
|
+
def init
|
54
|
+
@configuration = {
|
55
|
+
site: "https://api.linkedin.com",
|
56
|
+
authorize_path: '/uas/oauth/authenticate',
|
57
|
+
request_token_path: '/uas/oauth/requestToken',
|
58
|
+
access_token_path: '/uas/oauth/accessToken'
|
59
|
+
}
|
60
|
+
@user_info_path = "/v1/people/~"
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_user_hash
|
64
|
+
user_hash = {}
|
65
|
+
fields = self.user_info_fields.join(',')
|
66
|
+
response = @access_token.get("#{@user_info_path}:(#{fields})", 'x-li-format' => 'json')
|
67
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
68
|
+
user_hash[:uid] = user_hash[:user_info]['id'].to_s
|
69
|
+
user_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
def has_callback?
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
# calculates and returns the url to which the user should be redirected,
|
77
|
+
# to get authenticated at the external provider's site.
|
78
|
+
def login_url(params,session)
|
79
|
+
req_token = self.get_request_token
|
80
|
+
session[:request_token] = req_token.token
|
81
|
+
session[:request_token_secret] = req_token.secret
|
82
|
+
self.authorize_url({:request_token => req_token.token, :request_token_secret => req_token.secret})
|
83
|
+
end
|
84
|
+
|
85
|
+
# tries to login the user from access token
|
86
|
+
def process_callback(params,session)
|
87
|
+
args = {}
|
88
|
+
args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]})
|
89
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
90
|
+
@access_token = self.get_access_token(args)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
init
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module Controller
|
3
|
+
module Submodules
|
4
|
+
module External
|
5
|
+
module Providers
|
6
|
+
# This module adds support for OAuth with vkontakte.com.
|
7
|
+
# When included in the 'config.providers' option, it adds a new option, 'config.vkontakte'.
|
8
|
+
# Via this new option you can configure Vkontakte specific settings like your app's key and secret.
|
9
|
+
#
|
10
|
+
# config.vkontakte.key = <key>
|
11
|
+
# config.vkontakte.secret = <secret>
|
12
|
+
# ...
|
13
|
+
#
|
14
|
+
module Vkontakte
|
15
|
+
def self.included(base)
|
16
|
+
base.module_eval do
|
17
|
+
class << self
|
18
|
+
attr_reader :vkontakte # access to vkontakte_client.
|
19
|
+
|
20
|
+
def merge_vkontakte_defaults!
|
21
|
+
@defaults.merge!(:@vkontakte => VkontakteClient)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
merge_vkontakte_defaults!
|
25
|
+
update!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module VkontakteClient
|
30
|
+
class << self
|
31
|
+
attr_accessor :key,
|
32
|
+
:secret,
|
33
|
+
:callback_url,
|
34
|
+
:auth_path,
|
35
|
+
:token_path,
|
36
|
+
:site,
|
37
|
+
:scope,
|
38
|
+
:user_info_path,
|
39
|
+
:user_info_mapping
|
40
|
+
attr_reader :access_token
|
41
|
+
|
42
|
+
include Protocols::Oauth2
|
43
|
+
|
44
|
+
def init
|
45
|
+
@site = "https://oauth.vk.com/"
|
46
|
+
@user_info_url = "https://api.vk.com/method/getUserInfo"
|
47
|
+
@scope = nil
|
48
|
+
@auth_path = "/authorize"
|
49
|
+
@token_path = "/access_token"
|
50
|
+
@user_info_mapping = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_user_hash
|
54
|
+
user_hash = {}
|
55
|
+
response = @access_token.get("#{@user_info_url}?access_token=#{@access_token.token}")
|
56
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
57
|
+
if user_hash[:user_info]
|
58
|
+
user_hash[:user_info] = user_hash[:user_info]["response"]
|
59
|
+
end
|
60
|
+
user_hash[:uid] = user_hash[:user_info]['user_id']
|
61
|
+
user_hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def has_callback?
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
# calculates and returns the url to which the user should be redirected,
|
69
|
+
# to get authenticated at the external provider's site.
|
70
|
+
def login_url(params,session)
|
71
|
+
self.authorize_url({:authorize_url => @auth_path})
|
72
|
+
end
|
73
|
+
|
74
|
+
# tries to login the user from access token
|
75
|
+
def process_callback(params,session)
|
76
|
+
args = {}
|
77
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
78
|
+
options = {
|
79
|
+
:token_url => @token_path,
|
80
|
+
:token_method => :post
|
81
|
+
}
|
82
|
+
@access_token = self.get_access_token(args, options)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
init
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -58,7 +58,7 @@ module Sorcery
|
|
58
58
|
while current_controller != ActionController::Base
|
59
59
|
result = Config.controller_to_realm_map[current_controller.controller_name]
|
60
60
|
return result if result
|
61
|
-
current_controller =
|
61
|
+
current_controller = current_controller.superclass
|
62
62
|
end
|
63
63
|
nil
|
64
64
|
else
|
@@ -8,6 +8,15 @@ module Sorcery
|
|
8
8
|
module RememberMe
|
9
9
|
def self.included(base)
|
10
10
|
base.send(:include, InstanceMethods)
|
11
|
+
Config.module_eval do
|
12
|
+
class << self
|
13
|
+
attr_accessor :remember_me_httponly
|
14
|
+
def merge_remember_me_defaults!
|
15
|
+
@defaults.merge!(:@remember_me_httponly => true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
merge_remember_me_defaults!
|
19
|
+
end
|
11
20
|
Config.login_sources << :login_from_cookie
|
12
21
|
Config.after_login << :remember_me_if_asked_to
|
13
22
|
Config.after_logout << :forget_me!
|
@@ -60,7 +69,7 @@ module Sorcery
|
|
60
69
|
cookies.signed[:remember_me_token] = {
|
61
70
|
:value => user.send(user.sorcery_config.remember_me_token_attribute_name),
|
62
71
|
:expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name),
|
63
|
-
:httponly =>
|
72
|
+
:httponly => Config.remember_me_httponly,
|
64
73
|
:domain => Config.cookie_domain
|
65
74
|
}
|
66
75
|
end
|
@@ -69,4 +78,4 @@ module Sorcery
|
|
69
78
|
end
|
70
79
|
end
|
71
80
|
end
|
72
|
-
end
|
81
|
+
end
|
data/lib/sorcery/model.rb
CHANGED
@@ -17,39 +17,39 @@ module Sorcery
|
|
17
17
|
include InstanceMethods
|
18
18
|
include TemporaryToken
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
include_required_submodules!
|
22
22
|
|
23
23
|
# This runs the options block set in the initializer on the model class.
|
24
24
|
::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
|
25
|
-
|
25
|
+
|
26
26
|
init_mongoid_support! if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
|
27
27
|
init_mongo_mapper_support! if defined?(MongoMapper) and self.ancestors.include?(MongoMapper::Document)
|
28
28
|
|
29
29
|
init_orm_hooks!
|
30
|
-
|
30
|
+
|
31
31
|
@sorcery_config.after_config << :add_config_inheritance if @sorcery_config.subclasses_inherit_config
|
32
32
|
@sorcery_config.after_config.each { |c| send(c) }
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
protected
|
36
|
-
|
37
|
-
# includes required submodules into the model class,
|
36
|
+
|
37
|
+
# includes required submodules into the model class,
|
38
38
|
# which usually is called User.
|
39
39
|
def include_required_submodules!
|
40
40
|
self.class_eval do
|
41
41
|
@sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
|
42
42
|
@sorcery_config.submodules.each do |mod|
|
43
43
|
begin
|
44
|
-
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
44
|
+
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
45
45
|
rescue NameError
|
46
|
-
# don't stop on a missing submodule. Needed because some submodules are only defined
|
46
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined
|
47
47
|
# in the controller side.
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# defines mongoid fields on the model class,
|
54
54
|
# using 1.8.x hash syntax to perserve compatibility.
|
55
55
|
def init_mongoid_support!
|
@@ -62,7 +62,7 @@ module Sorcery
|
|
62
62
|
field sorcery_config.salt_attribute_name, :type => String
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
# defines mongo_mapper fields on the model class,
|
67
67
|
def init_mongo_mapper_support!
|
68
68
|
self.class_eval do
|
@@ -91,13 +91,13 @@ module Sorcery
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
module ClassMethods
|
96
96
|
# Returns the class instance variable for configuration, when called by the class itself.
|
97
97
|
def sorcery_config
|
98
98
|
@sorcery_config
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
# The default authentication method.
|
102
102
|
# Takes a username and password,
|
103
103
|
# Finds the user by the username and compares the user's password to the one supplied to the method.
|
@@ -112,17 +112,17 @@ module Sorcery
|
|
112
112
|
_salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
|
113
113
|
user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && credentials_match?(user.send(@sorcery_config.crypted_password_attribute_name),credentials[1],_salt)
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
# encrypt tokens using current encryption_provider.
|
117
117
|
def encrypt(*tokens)
|
118
118
|
return tokens.first if @sorcery_config.encryption_provider.nil?
|
119
|
-
|
119
|
+
|
120
120
|
set_encryption_attributes()
|
121
121
|
|
122
122
|
CryptoProviders::AES256.key = @sorcery_config.encryption_key
|
123
123
|
@sorcery_config.encryption_provider.encrypt(*tokens)
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
protected
|
127
127
|
|
128
128
|
def set_encryption_attributes()
|
@@ -135,7 +135,7 @@ module Sorcery
|
|
135
135
|
return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
|
136
136
|
@sorcery_config.encryption_provider.matches?(crypted, *tokens)
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
def add_config_inheritance
|
140
140
|
self.class_eval do
|
141
141
|
def self.inherited(subclass)
|
@@ -149,23 +149,23 @@ module Sorcery
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
end
|
154
|
-
|
154
|
+
|
155
155
|
module InstanceMethods
|
156
156
|
# Returns the class instance variable for configuration, when called by an instance.
|
157
157
|
def sorcery_config
|
158
158
|
self.class.sorcery_config
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
# identifies whether this user is regular, i.e. we hold his credentials in our db,
|
162
162
|
# or that he is external, and his credentials are saved elsewhere (twitter/facebook etc.).
|
163
163
|
def external?
|
164
164
|
send(sorcery_config.crypted_password_attribute_name).nil?
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
protected
|
168
|
-
|
168
|
+
|
169
169
|
# creates new salt and saves it.
|
170
170
|
# encrypts password with salt and saves it.
|
171
171
|
def encrypt_password
|
@@ -178,29 +178,29 @@ module Sorcery
|
|
178
178
|
config = sorcery_config
|
179
179
|
self.send(:"#{config.password_attribute_name}=", nil)
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
# calls the requested email method on the configured mailer
|
183
183
|
# supports both the ActionMailer 3 way of calling, and the plain old Ruby object way.
|
184
184
|
def generic_send_email(method, mailer)
|
185
185
|
config = sorcery_config
|
186
186
|
mail = config.send(mailer).send(config.send(method),self)
|
187
|
-
if defined?(ActionMailer) and config.send(mailer).
|
187
|
+
if defined?(ActionMailer) and config.send(mailer).kind_of?(Class) and config.send(mailer) < ActionMailer::Base
|
188
188
|
mail.deliver
|
189
189
|
end
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
193
193
|
# Each class which calls 'activate_sorcery!' receives an instance of this class.
|
194
|
-
# Every submodule which gets loaded may add accessors to this class so that all
|
194
|
+
# Every submodule which gets loaded may add accessors to this class so that all
|
195
195
|
# options will be configured from a single place.
|
196
196
|
class Config
|
197
197
|
|
198
198
|
attr_accessor :username_attribute_names, # change default username attribute, for example, to use :email
|
199
199
|
# as the login.
|
200
|
-
|
200
|
+
|
201
201
|
:password_attribute_name, # change *virtual* password attribute, the one which is used
|
202
202
|
# until an encrypted one is generated.
|
203
|
-
|
203
|
+
|
204
204
|
:email_attribute_name, # change default email attribute.
|
205
205
|
|
206
206
|
:downcase_username_before_authenticating, # downcase the username before trying to authenticate, default is false
|
@@ -211,17 +211,17 @@ module Sorcery
|
|
211
211
|
:stretches, # how many times to apply encryption to the password.
|
212
212
|
:encryption_key, # encryption key used to encrypt reversible encryptions such as
|
213
213
|
# AES256.
|
214
|
-
|
214
|
+
|
215
215
|
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for
|
216
216
|
# ActiveRecord's STI.
|
217
|
-
|
217
|
+
|
218
218
|
:submodules, # configured in config/application.rb
|
219
219
|
:before_authenticate, # an array of method names to call before authentication
|
220
220
|
# completes. used internally.
|
221
|
-
|
221
|
+
|
222
222
|
:after_config # an array of method names to call after configuration by user.
|
223
223
|
# used internally.
|
224
|
-
|
224
|
+
|
225
225
|
attr_reader :encryption_provider, # change default encryption_provider.
|
226
226
|
:custom_encryption_provider, # use an external encryption class.
|
227
227
|
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
|
@@ -247,26 +247,26 @@ module Sorcery
|
|
247
247
|
:@after_config => []
|
248
248
|
}
|
249
249
|
reset!
|
250
|
-
end
|
251
|
-
|
250
|
+
end
|
251
|
+
|
252
252
|
# Resets all configuration options to their default values.
|
253
253
|
def reset!
|
254
254
|
@defaults.each do |k,v|
|
255
255
|
instance_variable_set(k,v)
|
256
|
-
end
|
256
|
+
end
|
257
257
|
end
|
258
|
-
|
258
|
+
|
259
259
|
def username_attribute_names=(fields)
|
260
260
|
@username_attribute_names = fields.kind_of?(Array) ? fields : [fields]
|
261
261
|
end
|
262
|
-
|
262
|
+
|
263
263
|
def custom_encryption_provider=(provider)
|
264
264
|
@custom_encryption_provider = @encryption_provider = provider
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
def encryption_algorithm=(algo)
|
268
268
|
@encryption_algorithm = algo
|
269
|
-
@encryption_provider = case @encryption_algorithm
|
269
|
+
@encryption_provider = case @encryption_algorithm.to_sym
|
270
270
|
when :none then nil
|
271
271
|
when :md5 then CryptoProviders::MD5
|
272
272
|
when :sha1 then CryptoProviders::SHA1
|
@@ -275,10 +275,11 @@ module Sorcery
|
|
275
275
|
when :aes256 then CryptoProviders::AES256
|
276
276
|
when :bcrypt then CryptoProviders::BCrypt
|
277
277
|
when :custom then @custom_encryption_provider
|
278
|
+
else raise ArgumentError.new("Encryption algorithm supplied, #{algo}, is invalid")
|
278
279
|
end
|
279
280
|
end
|
280
|
-
|
281
|
+
|
281
282
|
end
|
282
|
-
|
283
|
+
|
283
284
|
end
|
284
285
|
end
|
data/sorcery.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "sorcery"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.8.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Noam Ben Ari"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-01-12"
|
13
13
|
s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password."
|
14
14
|
s.email = "nbenari@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -47,8 +47,10 @@ Gem::Specification.new do |s|
|
|
47
47
|
"lib/sorcery/controller/submodules/external/providers/facebook.rb",
|
48
48
|
"lib/sorcery/controller/submodules/external/providers/github.rb",
|
49
49
|
"lib/sorcery/controller/submodules/external/providers/google.rb",
|
50
|
+
"lib/sorcery/controller/submodules/external/providers/linkedin.rb",
|
50
51
|
"lib/sorcery/controller/submodules/external/providers/liveid.rb",
|
51
52
|
"lib/sorcery/controller/submodules/external/providers/twitter.rb",
|
53
|
+
"lib/sorcery/controller/submodules/external/providers/vkontakte.rb",
|
52
54
|
"lib/sorcery/controller/submodules/http_basic_auth.rb",
|
53
55
|
"lib/sorcery/controller/submodules/remember_me.rb",
|
54
56
|
"lib/sorcery/controller/submodules/session_timeout.rb",
|
@@ -310,7 +312,7 @@ Gem::Specification.new do |s|
|
|
310
312
|
|
311
313
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
312
314
|
s.add_runtime_dependency(%q<oauth>, ["~> 0.4.4"])
|
313
|
-
s.add_runtime_dependency(%q<oauth2>, ["~> 0.
|
315
|
+
s.add_runtime_dependency(%q<oauth2>, ["~> 0.8.0"])
|
314
316
|
s.add_runtime_dependency(%q<bcrypt-ruby>, ["~> 3.0.0"])
|
315
317
|
s.add_development_dependency(%q<abstract>, [">= 1.0.0"])
|
316
318
|
s.add_development_dependency(%q<rails>, [">= 3.0.0"])
|
@@ -329,7 +331,7 @@ Gem::Specification.new do |s|
|
|
329
331
|
s.add_development_dependency(%q<mongoid>, ["~> 2.4.4"])
|
330
332
|
else
|
331
333
|
s.add_dependency(%q<oauth>, ["~> 0.4.4"])
|
332
|
-
s.add_dependency(%q<oauth2>, ["~> 0.
|
334
|
+
s.add_dependency(%q<oauth2>, ["~> 0.8.0"])
|
333
335
|
s.add_dependency(%q<bcrypt-ruby>, ["~> 3.0.0"])
|
334
336
|
s.add_dependency(%q<abstract>, [">= 1.0.0"])
|
335
337
|
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
@@ -349,7 +351,7 @@ Gem::Specification.new do |s|
|
|
349
351
|
end
|
350
352
|
else
|
351
353
|
s.add_dependency(%q<oauth>, ["~> 0.4.4"])
|
352
|
-
s.add_dependency(%q<oauth2>, ["~> 0.
|
354
|
+
s.add_dependency(%q<oauth2>, ["~> 0.8.0"])
|
353
355
|
s.add_dependency(%q<bcrypt-ruby>, ["~> 3.0.0"])
|
354
356
|
s.add_dependency(%q<abstract>, [">= 1.0.0"])
|
355
357
|
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
data/spec/Gemfile
CHANGED
data/spec/Gemfile.lock
CHANGED
@@ -4,7 +4,7 @@ PATH
|
|
4
4
|
sorcery (0.7.13)
|
5
5
|
bcrypt-ruby (~> 3.0.0)
|
6
6
|
oauth (~> 0.4.4)
|
7
|
-
oauth2 (~> 0.
|
7
|
+
oauth2 (~> 0.8.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
@@ -44,10 +44,12 @@ GEM
|
|
44
44
|
diff-lcs (1.1.3)
|
45
45
|
erubis (2.6.6)
|
46
46
|
abstract (>= 1.0.0)
|
47
|
-
faraday (0.8.
|
47
|
+
faraday (0.8.4)
|
48
48
|
multipart-post (~> 1.1)
|
49
|
-
httpauth (0.
|
49
|
+
httpauth (0.2.0)
|
50
50
|
i18n (0.6.0)
|
51
|
+
jwt (0.1.5)
|
52
|
+
multi_json (>= 1.0)
|
51
53
|
linecache19 (0.5.12)
|
52
54
|
ruby_core_source (>= 0.1.4)
|
53
55
|
mail (2.2.19)
|
@@ -59,10 +61,12 @@ GEM
|
|
59
61
|
multi_json (1.1.0)
|
60
62
|
multipart-post (1.1.5)
|
61
63
|
oauth (0.4.5)
|
62
|
-
oauth2 (0.
|
63
|
-
faraday (~> 0.
|
64
|
+
oauth2 (0.8.0)
|
65
|
+
faraday (~> 0.8)
|
64
66
|
httpauth (~> 0.1)
|
67
|
+
jwt (~> 0.1.4)
|
65
68
|
multi_json (~> 1.0)
|
69
|
+
rack (~> 1.2)
|
66
70
|
polyglot (0.3.3)
|
67
71
|
rack (1.2.5)
|
68
72
|
rack-mount (0.6.14)
|
@@ -117,7 +121,7 @@ PLATFORMS
|
|
117
121
|
DEPENDENCIES
|
118
122
|
bcrypt-ruby
|
119
123
|
oauth (~> 0.4.4)
|
120
|
-
oauth2 (~> 0.
|
124
|
+
oauth2 (~> 0.8.0)
|
121
125
|
rails (= 3.0.3)
|
122
126
|
rspec (~> 2.5.0)
|
123
127
|
ruby-debug19
|
data/spec/rails3/Gemfile.lock
CHANGED
@@ -4,7 +4,7 @@ PATH
|
|
4
4
|
sorcery (0.7.13)
|
5
5
|
bcrypt-ruby (~> 3.0.0)
|
6
6
|
oauth (~> 0.4.4)
|
7
|
-
oauth2 (~> 0.
|
7
|
+
oauth2 (~> 0.8.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
@@ -54,11 +54,13 @@ GEM
|
|
54
54
|
diff-lcs (1.1.3)
|
55
55
|
erubis (2.6.6)
|
56
56
|
abstract (>= 1.0.0)
|
57
|
-
faraday (0.8.
|
57
|
+
faraday (0.8.4)
|
58
58
|
multipart-post (~> 1.1)
|
59
59
|
ffi (1.0.11)
|
60
|
-
httpauth (0.
|
60
|
+
httpauth (0.2.0)
|
61
61
|
i18n (0.6.0)
|
62
|
+
jwt (0.1.5)
|
63
|
+
multi_json (>= 1.0)
|
62
64
|
launchy (2.0.5)
|
63
65
|
addressable (~> 2.2.6)
|
64
66
|
linecache19 (0.5.12)
|
@@ -72,11 +74,13 @@ GEM
|
|
72
74
|
multi_json (1.1.0)
|
73
75
|
multipart-post (1.1.5)
|
74
76
|
nokogiri (1.5.0)
|
75
|
-
oauth (0.4.
|
76
|
-
oauth2 (0.
|
77
|
-
faraday (~> 0.
|
77
|
+
oauth (0.4.7)
|
78
|
+
oauth2 (0.8.0)
|
79
|
+
faraday (~> 0.8)
|
78
80
|
httpauth (~> 0.1)
|
81
|
+
jwt (~> 0.1.4)
|
79
82
|
multi_json (~> 1.0)
|
83
|
+
rack (~> 1.2)
|
80
84
|
polyglot (0.3.3)
|
81
85
|
rack (1.2.5)
|
82
86
|
rack-mount (0.6.14)
|
@@ -4,7 +4,7 @@ PATH
|
|
4
4
|
sorcery (0.7.13)
|
5
5
|
bcrypt-ruby (~> 3.0.0)
|
6
6
|
oauth (~> 0.4.4)
|
7
|
-
oauth2 (~> 0.
|
7
|
+
oauth2 (~> 0.8.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
@@ -48,10 +48,12 @@ GEM
|
|
48
48
|
diff-lcs (1.1.3)
|
49
49
|
erubis (2.6.6)
|
50
50
|
abstract (>= 1.0.0)
|
51
|
-
faraday (0.8.
|
51
|
+
faraday (0.8.4)
|
52
52
|
multipart-post (~> 1.1)
|
53
|
-
httpauth (0.
|
53
|
+
httpauth (0.2.0)
|
54
54
|
i18n (0.6.0)
|
55
|
+
jwt (0.1.5)
|
56
|
+
multi_json (>= 1.0)
|
55
57
|
linecache19 (0.5.12)
|
56
58
|
ruby_core_source (>= 0.1.4)
|
57
59
|
mail (2.2.19)
|
@@ -69,11 +71,13 @@ GEM
|
|
69
71
|
plucky (~> 0.4.0)
|
70
72
|
multi_json (1.1.0)
|
71
73
|
multipart-post (1.1.5)
|
72
|
-
oauth (0.4.
|
73
|
-
oauth2 (0.
|
74
|
-
faraday (~> 0.
|
74
|
+
oauth (0.4.7)
|
75
|
+
oauth2 (0.8.0)
|
76
|
+
faraday (~> 0.8)
|
75
77
|
httpauth (~> 0.1)
|
78
|
+
jwt (~> 0.1.4)
|
76
79
|
multi_json (~> 1.0)
|
80
|
+
rack (~> 1.2)
|
77
81
|
plucky (0.4.4)
|
78
82
|
mongo (~> 1.5)
|
79
83
|
polyglot (0.3.3)
|
@@ -4,7 +4,7 @@ PATH
|
|
4
4
|
sorcery (0.7.13)
|
5
5
|
bcrypt-ruby (~> 3.0.0)
|
6
6
|
oauth (~> 0.4.4)
|
7
|
-
oauth2 (~> 0.
|
7
|
+
oauth2 (~> 0.8.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
@@ -47,10 +47,12 @@ GEM
|
|
47
47
|
diff-lcs (1.1.3)
|
48
48
|
erubis (2.6.6)
|
49
49
|
abstract (>= 1.0.0)
|
50
|
-
faraday (0.8.
|
50
|
+
faraday (0.8.4)
|
51
51
|
multipart-post (~> 1.1)
|
52
|
-
httpauth (0.
|
52
|
+
httpauth (0.2.0)
|
53
53
|
i18n (0.6.0)
|
54
|
+
jwt (0.1.5)
|
55
|
+
multi_json (>= 1.0)
|
54
56
|
linecache19 (0.5.12)
|
55
57
|
ruby_core_source (>= 0.1.4)
|
56
58
|
mail (2.2.19)
|
@@ -67,11 +69,13 @@ GEM
|
|
67
69
|
tzinfo (~> 0.3.22)
|
68
70
|
multi_json (1.1.0)
|
69
71
|
multipart-post (1.1.5)
|
70
|
-
oauth (0.4.
|
71
|
-
oauth2 (0.
|
72
|
-
faraday (~> 0.
|
72
|
+
oauth (0.4.7)
|
73
|
+
oauth2 (0.8.0)
|
74
|
+
faraday (~> 0.8)
|
73
75
|
httpauth (~> 0.1)
|
76
|
+
jwt (~> 0.1.4)
|
74
77
|
multi_json (~> 1.0)
|
78
|
+
rack (~> 1.2)
|
75
79
|
polyglot (0.3.3)
|
76
80
|
rack (1.2.5)
|
77
81
|
rack-mount (0.6.14)
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sorcery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.8.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Noam Ben Ari
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2013-01-12 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: oauth
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.8.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: *id002
|
@@ -250,8 +250,10 @@ files:
|
|
250
250
|
- lib/sorcery/controller/submodules/external/providers/facebook.rb
|
251
251
|
- lib/sorcery/controller/submodules/external/providers/github.rb
|
252
252
|
- lib/sorcery/controller/submodules/external/providers/google.rb
|
253
|
+
- lib/sorcery/controller/submodules/external/providers/linkedin.rb
|
253
254
|
- lib/sorcery/controller/submodules/external/providers/liveid.rb
|
254
255
|
- lib/sorcery/controller/submodules/external/providers/twitter.rb
|
256
|
+
- lib/sorcery/controller/submodules/external/providers/vkontakte.rb
|
255
257
|
- lib/sorcery/controller/submodules/http_basic_auth.rb
|
256
258
|
- lib/sorcery/controller/submodules/remember_me.rb
|
257
259
|
- lib/sorcery/controller/submodules/session_timeout.rb
|