sorcery 0.7.6 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +3 -0
- data/Gemfile +9 -4
- data/Gemfile.lock +99 -58
- data/README.rdoc +33 -8
- data/Rakefile +6 -7
- data/VERSION +1 -1
- data/lib/generators/sorcery/install_generator.rb +9 -7
- data/lib/generators/sorcery/templates/initializer.rb +324 -127
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +2 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +2 -2
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +16 -4
- data/lib/sorcery/controller/submodules/external/providers/github.rb +6 -4
- data/lib/sorcery/controller/submodules/external/providers/google.rb +4 -4
- data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +101 -0
- data/lib/sorcery/controller/submodules/external/providers/liveid.rb +1 -1
- data/lib/sorcery/controller/submodules/external/providers/vkontakte.rb +94 -0
- data/lib/sorcery/controller/submodules/external.rb +83 -15
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
- data/lib/sorcery/controller/submodules/remember_me.rb +11 -2
- data/lib/sorcery/controller.rb +14 -6
- data/lib/sorcery/crypto_providers/bcrypt.rb +1 -0
- data/lib/sorcery/model/adapters/active_record.rb +9 -4
- data/lib/sorcery/model/adapters/mongo_mapper.rb +16 -14
- data/lib/sorcery/model/adapters/mongoid.rb +12 -6
- data/lib/sorcery/model/submodules/brute_force_protection.rb +44 -13
- data/lib/sorcery/model/submodules/remember_me.rb +4 -6
- data/lib/sorcery/model/submodules/reset_password.rb +14 -7
- data/lib/sorcery/model/submodules/user_activation.rb +14 -6
- data/lib/sorcery/model.rb +40 -39
- data/lib/sorcery/railties/tasks.rake +2 -0
- data/lib/sorcery.rb +3 -1
- data/sorcery.gemspec +31 -141
- data/spec/Gemfile +1 -1
- data/spec/Gemfile.lock +20 -19
- data/spec/README.md +8 -8
- data/spec/rails3/Gemfile +1 -0
- data/spec/rails3/Gemfile.lock +27 -24
- data/spec/rails3/app/controllers/application_controller.rb +54 -0
- data/spec/rails3/app/mailers/sorcery_mailer.rb +7 -0
- data/spec/rails3/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
- data/spec/rails3/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +2 -0
- data/spec/rails3/spec/controller_activity_logging_spec.rb +3 -0
- data/spec/rails3/spec/controller_brute_force_protection_spec.rb +23 -1
- data/spec/rails3/spec/controller_oauth2_spec.rb +162 -24
- data/spec/rails3/spec/controller_oauth_spec.rb +111 -6
- data/spec/rails3/spec/controller_spec.rb +7 -0
- data/spec/rails3_mongo_mapper/Gemfile +2 -1
- data/spec/rails3_mongo_mapper/Gemfile.lock +37 -39
- data/spec/rails3_mongo_mapper/app/controllers/application_controller.rb +14 -0
- data/spec/rails3_mongo_mapper/spec/controller_spec.rb +7 -0
- data/spec/rails3_mongoid/Gemfile +1 -0
- data/spec/rails3_mongoid/Gemfile.lock +28 -25
- data/spec/rails3_mongoid/app/controllers/application_controller.rb +14 -0
- data/spec/rails3_mongoid/config/mongoid.yml +1 -1
- data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +11 -11
- data/spec/rails3_mongoid/spec/controller_spec.rb +7 -0
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +20 -1
- data/spec/shared_examples/controller_oauth_shared_examples.rb +18 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +71 -41
- data/spec/shared_examples/user_reset_password_shared_examples.rb +76 -31
- data/spec/sorcery_crypto_providers_spec.rb +9 -0
- metadata +159 -246
|
@@ -12,15 +12,25 @@ module Sorcery
|
|
|
12
12
|
:lock_expires_at_attribute_name, # this field indicates whether user
|
|
13
13
|
# is banned and when it will be active again.
|
|
14
14
|
:consecutive_login_retries_amount_limit, # how many failed logins allowed.
|
|
15
|
-
:login_lock_time_period
|
|
15
|
+
:login_lock_time_period, # how long the user should be banned.
|
|
16
16
|
# in seconds. 0 for permanent.
|
|
17
|
+
|
|
18
|
+
:unlock_token_attribute_name, # Unlock token attribute name
|
|
19
|
+
:unlock_token_email_method_name, # Mailer method name
|
|
20
|
+
:unlock_token_mailer_disabled, # When true, dont send unlock token via email
|
|
21
|
+
:unlock_token_mailer # Mailer class
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
base.sorcery_config.instance_eval do
|
|
20
25
|
@defaults.merge!(:@failed_logins_count_attribute_name => :failed_logins_count,
|
|
21
26
|
:@lock_expires_at_attribute_name => :lock_expires_at,
|
|
22
27
|
:@consecutive_login_retries_amount_limit => 50,
|
|
23
|
-
:@login_lock_time_period => 60 * 60
|
|
28
|
+
:@login_lock_time_period => 60 * 60,
|
|
29
|
+
|
|
30
|
+
:@unlock_token_attribute_name => :unlock_token,
|
|
31
|
+
:@unlock_token_email_method_name => :send_unlock_token_email,
|
|
32
|
+
:@unlock_token_mailer_disabled => false,
|
|
33
|
+
:@unlock_token_mailer => nil)
|
|
24
34
|
reset!
|
|
25
35
|
end
|
|
26
36
|
|
|
@@ -34,16 +44,24 @@ module Sorcery
|
|
|
34
44
|
end
|
|
35
45
|
|
|
36
46
|
module ClassMethods
|
|
47
|
+
def load_from_unlock_token(token)
|
|
48
|
+
return nil if token.blank?
|
|
49
|
+
user = find_by_sorcery_token(sorcery_config.unlock_token_attribute_name,token)
|
|
50
|
+
user
|
|
51
|
+
end
|
|
52
|
+
|
|
37
53
|
protected
|
|
38
54
|
|
|
39
55
|
def define_brute_force_protection_mongoid_fields
|
|
40
|
-
field sorcery_config.failed_logins_count_attribute_name, :type => Integer
|
|
56
|
+
field sorcery_config.failed_logins_count_attribute_name, :type => Integer, :default => 0
|
|
41
57
|
field sorcery_config.lock_expires_at_attribute_name, :type => Time
|
|
58
|
+
field sorcery_config.unlock_token_attribute_name, :type => String
|
|
42
59
|
end
|
|
43
60
|
|
|
44
61
|
def define_brute_force_protection_mongo_mapper_fields
|
|
45
|
-
key sorcery_config.failed_logins_count_attribute_name, Integer
|
|
62
|
+
key sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0
|
|
46
63
|
key sorcery_config.lock_expires_at_attribute_name, Time
|
|
64
|
+
key sorcery_config.unlock_token_attribute_name, String
|
|
47
65
|
end
|
|
48
66
|
end
|
|
49
67
|
|
|
@@ -54,29 +72,42 @@ module Sorcery
|
|
|
54
72
|
config = sorcery_config
|
|
55
73
|
return if !unlocked?
|
|
56
74
|
self.increment(config.failed_logins_count_attribute_name)
|
|
57
|
-
self.
|
|
75
|
+
self.update_many_attributes(config.failed_logins_count_attribute_name => self.send(config.failed_logins_count_attribute_name))
|
|
58
76
|
self.lock! if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
|
|
59
77
|
end
|
|
60
78
|
|
|
79
|
+
# /!\
|
|
80
|
+
# Moved out of protected for use like activate! in controller
|
|
81
|
+
# /!\
|
|
82
|
+
def unlock!
|
|
83
|
+
config = sorcery_config
|
|
84
|
+
attributes = {config.lock_expires_at_attribute_name => nil,
|
|
85
|
+
config.failed_logins_count_attribute_name => 0}
|
|
86
|
+
attributes[config.unlock_token_attribute_name] = nil unless config.unlock_token_mailer_disabled or config.unlock_token_mailer.nil?
|
|
87
|
+
self.update_many_attributes(attributes)
|
|
88
|
+
end
|
|
89
|
+
|
|
61
90
|
protected
|
|
62
91
|
|
|
63
92
|
def lock!
|
|
64
93
|
config = sorcery_config
|
|
65
|
-
|
|
66
|
-
self.save!(:validate => false)
|
|
67
|
-
end
|
|
94
|
+
attributes = {config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period}
|
|
68
95
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
self.
|
|
96
|
+
unless config.unlock_token_mailer_disabled || config.unlock_token_mailer.nil?
|
|
97
|
+
attributes[config.unlock_token_attribute_name] = TemporaryToken.generate_random_token
|
|
98
|
+
send_unlock_token_email!
|
|
99
|
+
end
|
|
100
|
+
self.update_many_attributes(attributes)
|
|
74
101
|
end
|
|
75
102
|
|
|
76
103
|
def unlocked?
|
|
77
104
|
config = sorcery_config
|
|
78
105
|
self.send(config.lock_expires_at_attribute_name).nil?
|
|
79
106
|
end
|
|
107
|
+
|
|
108
|
+
def send_unlock_token_email!
|
|
109
|
+
generic_send_email(:unlock_token_email_method_name, :unlock_token_mailer) unless sorcery_config.unlock_token_email_method_name.nil? or sorcery_config.unlock_token_mailer_disabled == true
|
|
110
|
+
end
|
|
80
111
|
|
|
81
112
|
# Prevents a locked user from logging in, and unlocks users that expired their lock time.
|
|
82
113
|
# Runs as a hook before authenticate.
|
|
@@ -49,17 +49,15 @@ module Sorcery
|
|
|
49
49
|
# You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
|
|
50
50
|
def remember_me!
|
|
51
51
|
config = sorcery_config
|
|
52
|
-
self.
|
|
53
|
-
|
|
54
|
-
self.save!(:validate => false)
|
|
52
|
+
self.update_many_attributes(config.remember_me_token_attribute_name => TemporaryToken.generate_random_token,
|
|
53
|
+
config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for)
|
|
55
54
|
end
|
|
56
55
|
|
|
57
56
|
# You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method.
|
|
58
57
|
def forget_me!
|
|
59
58
|
config = sorcery_config
|
|
60
|
-
self.
|
|
61
|
-
|
|
62
|
-
self.save!(:validate => false)
|
|
59
|
+
self.update_many_attributes(config.remember_me_token_attribute_name => nil,
|
|
60
|
+
config.remember_me_token_expires_at_attribute_name => nil)
|
|
63
61
|
end
|
|
64
62
|
end
|
|
65
63
|
end
|
|
@@ -18,6 +18,11 @@ module Sorcery
|
|
|
18
18
|
# protection.
|
|
19
19
|
|
|
20
20
|
:reset_password_mailer, # mailer class. Needed.
|
|
21
|
+
|
|
22
|
+
:reset_password_mailer_disabled, # when true sorcery will not automatically
|
|
23
|
+
# email password reset details and allow you to
|
|
24
|
+
# manually handle how and when email is sent
|
|
25
|
+
|
|
21
26
|
:reset_password_email_method_name, # reset password email method on your
|
|
22
27
|
# mailer class.
|
|
23
28
|
|
|
@@ -34,6 +39,7 @@ module Sorcery
|
|
|
34
39
|
:@reset_password_token_expires_at_attribute_name => :reset_password_token_expires_at,
|
|
35
40
|
:@reset_password_email_sent_at_attribute_name => :reset_password_email_sent_at,
|
|
36
41
|
:@reset_password_mailer => nil,
|
|
42
|
+
:@reset_password_mailer_disabled => false,
|
|
37
43
|
:@reset_password_email_method_name => :reset_password_email,
|
|
38
44
|
:@reset_password_expiration_period => nil,
|
|
39
45
|
:@reset_password_time_between_emails => 5 * 60 )
|
|
@@ -64,10 +70,11 @@ module Sorcery
|
|
|
64
70
|
|
|
65
71
|
protected
|
|
66
72
|
|
|
67
|
-
# This submodule requires the developer to define his own mailer class to be used by it
|
|
73
|
+
# This submodule requires the developer to define his own mailer class to be used by it
|
|
74
|
+
# when reset_password_mailer_disabled is false
|
|
68
75
|
def validate_mailer_defined
|
|
69
76
|
msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)."
|
|
70
|
-
raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
|
|
77
|
+
raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil and @sorcery_config.reset_password_mailer_disabled == false
|
|
71
78
|
end
|
|
72
79
|
|
|
73
80
|
def define_reset_password_mongoid_fields
|
|
@@ -89,12 +96,12 @@ module Sorcery
|
|
|
89
96
|
config = sorcery_config
|
|
90
97
|
# hammering protection
|
|
91
98
|
return false if config.reset_password_time_between_emails && self.send(config.reset_password_email_sent_at_attribute_name) && self.send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.ago.utc
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
attributes = {config.reset_password_token_attribute_name => TemporaryToken.generate_random_token,
|
|
100
|
+
config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone}
|
|
101
|
+
attributes[config.reset_password_token_expires_at_attribute_name] = Time.now.in_time_zone + config.reset_password_expiration_period if config.reset_password_expiration_period
|
|
95
102
|
self.class.transaction do
|
|
96
|
-
self.
|
|
97
|
-
generic_send_email(:reset_password_email_method_name, :reset_password_mailer)
|
|
103
|
+
self.update_many_attributes(attributes)
|
|
104
|
+
generic_send_email(:reset_password_email_method_name, :reset_password_mailer) unless config.reset_password_mailer_disabled
|
|
98
105
|
end
|
|
99
106
|
end
|
|
100
107
|
|
|
@@ -20,7 +20,13 @@ module Sorcery
|
|
|
20
20
|
:activation_token_expiration_period, # how many seconds before the activation code
|
|
21
21
|
# expires. nil for never expires.
|
|
22
22
|
|
|
23
|
-
:user_activation_mailer, # your mailer class. Required
|
|
23
|
+
:user_activation_mailer, # your mailer class. Required when
|
|
24
|
+
# activation_mailer_disabled == false.
|
|
25
|
+
|
|
26
|
+
:activation_mailer_disabled, # when true sorcery will not automatically
|
|
27
|
+
# email activation details and allow you to
|
|
28
|
+
# manually handle how and when email is sent
|
|
29
|
+
|
|
24
30
|
:activation_needed_email_method_name, # activation needed email method on your
|
|
25
31
|
# mailer class.
|
|
26
32
|
|
|
@@ -37,6 +43,7 @@ module Sorcery
|
|
|
37
43
|
:@activation_token_expires_at_attribute_name => :activation_token_expires_at,
|
|
38
44
|
:@activation_token_expiration_period => nil,
|
|
39
45
|
:@user_activation_mailer => nil,
|
|
46
|
+
:@activation_mailer_disabled => false,
|
|
40
47
|
:@activation_needed_email_method_name => :activation_needed_email,
|
|
41
48
|
:@activation_success_email_method_name => :activation_success_email,
|
|
42
49
|
:@prevent_non_active_users_to_login => true)
|
|
@@ -47,7 +54,7 @@ module Sorcery
|
|
|
47
54
|
# don't setup activation if no password supplied - this user is created automatically
|
|
48
55
|
before_create :setup_activation, :if => Proc.new { |user| user.send(sorcery_config.password_attribute_name).present? }
|
|
49
56
|
# don't send activation needed email if no crypted password created - this user is external (OAuth etc.)
|
|
50
|
-
after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external?}
|
|
57
|
+
after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external? }
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
base.sorcery_config.after_config << :validate_mailer_defined
|
|
@@ -74,10 +81,11 @@ module Sorcery
|
|
|
74
81
|
|
|
75
82
|
protected
|
|
76
83
|
|
|
77
|
-
# This submodule requires the developer to define his own mailer class to be used by it
|
|
84
|
+
# This submodule requires the developer to define his own mailer class to be used by it
|
|
85
|
+
# when activation_mailer_disabled is false
|
|
78
86
|
def validate_mailer_defined
|
|
79
87
|
msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
|
|
80
|
-
raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
|
|
88
|
+
raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil and @sorcery_config.activation_mailer_disabled == false
|
|
81
89
|
end
|
|
82
90
|
|
|
83
91
|
def define_user_activation_mongoid_fields
|
|
@@ -119,11 +127,11 @@ module Sorcery
|
|
|
119
127
|
|
|
120
128
|
# called automatically after user initial creation.
|
|
121
129
|
def send_activation_needed_email!
|
|
122
|
-
generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil?
|
|
130
|
+
generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil? or sorcery_config.activation_mailer_disabled == true
|
|
123
131
|
end
|
|
124
132
|
|
|
125
133
|
def send_activation_success_email!
|
|
126
|
-
generic_send_email(:activation_success_email_method_name, :user_activation_mailer) unless sorcery_config.activation_success_email_method_name.nil?
|
|
134
|
+
generic_send_email(:activation_success_email_method_name, :user_activation_mailer) unless sorcery_config.activation_success_email_method_name.nil? or sorcery_config.activation_mailer_disabled == true
|
|
127
135
|
end
|
|
128
136
|
|
|
129
137
|
def prevent_non_active_login
|
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
|
|
@@ -3,6 +3,8 @@ require 'fileutils'
|
|
|
3
3
|
namespace :sorcery do
|
|
4
4
|
desc "Adds sorcery's initializer file"
|
|
5
5
|
task :bootstrap do
|
|
6
|
+
warn "This task is obsolete.\nUse \"rails g sorcery:install\" now.\nSee README for more information."
|
|
7
|
+
|
|
6
8
|
src = File.join(File.dirname(__FILE__), '..', 'initializers', 'initializer.rb')
|
|
7
9
|
target = File.join(Rails.root, "config", "initializers", "sorcery.rb")
|
|
8
10
|
FileUtils.cp(src, target)
|
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
|