sorcery 0.1.3 → 0.2.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/Gemfile +4 -3
- data/Gemfile.lock +16 -13
- data/LICENSE.txt +1 -1
- data/README.rdoc +53 -36
- data/Rakefile +7 -13
- data/VERSION +1 -1
- data/lib/sorcery/controller/submodules/activity_logging.rb +58 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +15 -69
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +13 -5
- data/lib/sorcery/controller/submodules/oauth/oauth1.rb +25 -0
- data/lib/sorcery/controller/submodules/oauth/oauth2.rb +23 -0
- data/lib/sorcery/controller/submodules/oauth/providers/facebook.rb +64 -0
- data/lib/sorcery/controller/submodules/oauth/providers/twitter.rb +61 -0
- data/lib/sorcery/controller/submodules/oauth.rb +95 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
- data/lib/sorcery/controller/submodules/session_timeout.rb +10 -2
- data/lib/sorcery/controller.rb +40 -22
- data/lib/sorcery/crypto_providers/bcrypt.rb +1 -5
- data/lib/sorcery/engine.rb +9 -2
- data/lib/sorcery/model/submodules/activity_logging.rb +40 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +79 -0
- data/lib/sorcery/model/submodules/oauth.rb +53 -0
- data/lib/sorcery/model/submodules/remember_me.rb +6 -2
- data/lib/sorcery/model/submodules/reset_password.rb +96 -0
- data/lib/sorcery/model/submodules/user_activation.rb +40 -19
- data/lib/sorcery/model/temporary_token.rb +22 -0
- data/lib/sorcery/model.rb +10 -3
- data/lib/sorcery/test_helpers.rb +84 -0
- data/lib/sorcery.rb +16 -1
- data/sorcery.gemspec +84 -43
- data/spec/Gemfile +3 -2
- data/spec/Gemfile.lock +15 -2
- data/spec/rails3/app_root/.rspec +1 -0
- data/spec/rails3/{Gemfile → app_root/Gemfile} +5 -3
- data/spec/rails3/{Gemfile.lock → app_root/Gemfile.lock} +25 -2
- data/spec/rails3/app_root/app/controllers/application_controller.rb +44 -3
- data/spec/rails3/app_root/app/models/authentication.rb +3 -0
- data/spec/rails3/app_root/app/models/user.rb +4 -1
- data/spec/rails3/app_root/config/application.rb +1 -3
- data/spec/rails3/app_root/config/routes.rb +1 -10
- data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +6 -4
- data/spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
- data/spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
- data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +4 -4
- data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
- data/spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/rails3/app_root/spec/controller_activity_logging_spec.rb +84 -0
- data/spec/rails3/app_root/spec/controller_brute_force_protection_spec.rb +65 -0
- data/spec/rails3/{controller_http_basic_auth_spec.rb → app_root/spec/controller_http_basic_auth_spec.rb} +13 -3
- data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +117 -0
- data/spec/rails3/app_root/spec/controller_oauth_spec.rb +117 -0
- data/spec/rails3/{controller_remember_me_spec.rb → app_root/spec/controller_remember_me_spec.rb} +4 -4
- data/spec/rails3/{controller_session_timeout_spec.rb → app_root/spec/controller_session_timeout_spec.rb} +5 -4
- data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +23 -16
- data/spec/rails3/app_root/spec/spec_helper.orig.rb +27 -0
- data/spec/rails3/app_root/spec/spec_helper.rb +61 -0
- data/spec/rails3/{user_activation_spec.rb → app_root/spec/user_activation_spec.rb} +60 -20
- data/spec/rails3/app_root/spec/user_activity_logging_spec.rb +36 -0
- data/spec/rails3/app_root/spec/user_brute_force_protection_spec.rb +76 -0
- data/spec/rails3/app_root/spec/user_oauth_spec.rb +39 -0
- data/spec/rails3/{user_remember_me_spec.rb → app_root/spec/user_remember_me_spec.rb} +4 -4
- data/spec/rails3/app_root/spec/user_reset_password_spec.rb +178 -0
- data/spec/rails3/{user_spec.rb → app_root/spec/user_spec.rb} +68 -38
- metadata +144 -63
- data/features/support/env.rb +0 -13
- data/lib/sorcery/model/submodules/password_reset.rb +0 -64
- data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +0 -9
- data/spec/rails3/app_root/test/fixtures/users.yml +0 -9
- data/spec/rails3/app_root/test/performance/browsing_test.rb +0 -9
- data/spec/rails3/app_root/test/test_helper.rb +0 -13
- data/spec/rails3/app_root/test/unit/user_test.rb +0 -8
- data/spec/rails3/controller_brute_force_protection_spec.rb +0 -72
- data/spec/rails3/spec_helper.rb +0 -115
- data/spec/rails3/user_password_reset_spec.rb +0 -76
- /data/spec/rails3/{Rakefile → app_root/Rakefile} +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Model
|
|
3
|
+
module Submodules
|
|
4
|
+
# This submodule adds the ability to reset password via email confirmation.
|
|
5
|
+
# When the user requests an email is sent to him with a url.
|
|
6
|
+
# The url includes a token, which is also saved with the user's record in the db.
|
|
7
|
+
# The token has configurable expiration.
|
|
8
|
+
# When the user clicks the url in the email, providing the token has not yet expired, he will be able to reset his password via a form.
|
|
9
|
+
#
|
|
10
|
+
# When using this submodule, supplying a mailer is mandatory.
|
|
11
|
+
module ResetPassword
|
|
12
|
+
def self.included(base)
|
|
13
|
+
base.sorcery_config.class_eval do
|
|
14
|
+
attr_accessor :reset_password_token_attribute_name, # reset password code attribute name.
|
|
15
|
+
:reset_password_token_expires_at_attribute_name, # expires at attribute name.
|
|
16
|
+
:reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering protection.
|
|
17
|
+
:reset_password_mailer, # mailer class. Needed.
|
|
18
|
+
:reset_password_email_method_name, # reset password email method on your mailer class.
|
|
19
|
+
:reset_password_expiration_period, # how many seconds before the reset request expires. nil for never expires.
|
|
20
|
+
:reset_password_time_between_emails # hammering protection, how long to wait before allowing another email to be sent.
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
base.sorcery_config.instance_eval do
|
|
25
|
+
@defaults.merge!(:@reset_password_token_attribute_name => :reset_password_token,
|
|
26
|
+
:@reset_password_token_expires_at_attribute_name => :reset_password_token_expires_at,
|
|
27
|
+
:@reset_password_email_sent_at_attribute_name => :reset_password_email_sent_at,
|
|
28
|
+
:@reset_password_mailer => nil,
|
|
29
|
+
:@reset_password_email_method_name => :reset_password_email,
|
|
30
|
+
:@reset_password_expiration_period => nil,
|
|
31
|
+
:@reset_password_time_between_emails => 5.minutes )
|
|
32
|
+
|
|
33
|
+
reset!
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
base.sorcery_config.after_config << :validate_mailer_defined
|
|
37
|
+
|
|
38
|
+
base.extend(ClassMethods)
|
|
39
|
+
base.send(:include, TemporaryToken)
|
|
40
|
+
base.send(:include, InstanceMethods)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
module ClassMethods
|
|
44
|
+
# Find user by token, also checks for expiration.
|
|
45
|
+
# Returns the user if token found and is valid.
|
|
46
|
+
def load_from_reset_password_token(token)
|
|
47
|
+
token_attr_name = @sorcery_config.reset_password_token_attribute_name
|
|
48
|
+
token_expiration_date_attr = @sorcery_config.reset_password_token_expires_at_attribute_name
|
|
49
|
+
load_from_token(token, token_attr_name, token_expiration_date_attr)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
protected
|
|
53
|
+
|
|
54
|
+
# This submodule requires the developer to define his own mailer class to be used by it.
|
|
55
|
+
def validate_mailer_defined
|
|
56
|
+
msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)."
|
|
57
|
+
raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
module InstanceMethods
|
|
63
|
+
# generates a reset code with expiration and sends an email to the user.
|
|
64
|
+
def deliver_reset_password_instructions!
|
|
65
|
+
config = sorcery_config
|
|
66
|
+
# hammering protection
|
|
67
|
+
return 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
|
|
68
|
+
self.send(:"#{config.reset_password_token_attribute_name}=", generate_random_token)
|
|
69
|
+
self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", Time.now.utc + config.reset_password_expiration_period) if config.reset_password_expiration_period
|
|
70
|
+
self.send(:"#{config.reset_password_email_sent_at_attribute_name}=", Time.now.utc)
|
|
71
|
+
self.class.transaction do
|
|
72
|
+
self.save!(:validate => false)
|
|
73
|
+
generic_send_email(:reset_password_email_method_name, :reset_password_mailer)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Clears token and tries to update the new password for the user.
|
|
78
|
+
def reset_password!(params)
|
|
79
|
+
clear_reset_password_token
|
|
80
|
+
update_attributes(params)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
protected
|
|
84
|
+
|
|
85
|
+
# Clears the token.
|
|
86
|
+
def clear_reset_password_token
|
|
87
|
+
config = sorcery_config
|
|
88
|
+
self.send(:"#{config.reset_password_token_attribute_name}=", nil)
|
|
89
|
+
self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -8,27 +8,33 @@ module Sorcery
|
|
|
8
8
|
module UserActivation
|
|
9
9
|
def self.included(base)
|
|
10
10
|
base.sorcery_config.class_eval do
|
|
11
|
-
attr_accessor :activation_state_attribute_name,
|
|
12
|
-
:
|
|
13
|
-
:
|
|
14
|
-
:
|
|
15
|
-
:
|
|
16
|
-
:
|
|
11
|
+
attr_accessor :activation_state_attribute_name, # the attribute name to hold activation state (active/pending).
|
|
12
|
+
:activation_token_attribute_name, # the attribute name to hold activation code (sent by email).
|
|
13
|
+
:activation_token_expires_at_attribute_name, # the attribute name to hold activation code expiration date.
|
|
14
|
+
:activation_token_expiration_period, # how many seconds before the activation code expires. nil for never expires.
|
|
15
|
+
:user_activation_mailer, # your mailer class. Required.
|
|
16
|
+
:activation_needed_email_method_name, # activation needed email method on your mailer class.
|
|
17
|
+
:activation_success_email_method_name, # activation success email method on your mailer class.
|
|
18
|
+
:prevent_non_active_users_to_login # do you want to prevent or allow users that did not activate by email to login?
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
base.sorcery_config.instance_eval do
|
|
20
|
-
@defaults.merge!(:@activation_state_attribute_name
|
|
21
|
-
:@
|
|
22
|
-
:@
|
|
23
|
-
:@
|
|
24
|
-
:@
|
|
25
|
-
:@
|
|
22
|
+
@defaults.merge!(:@activation_state_attribute_name => :activation_state,
|
|
23
|
+
:@activation_token_attribute_name => :activation_token,
|
|
24
|
+
:@activation_token_expires_at_attribute_name => :activation_token_expires_at,
|
|
25
|
+
:@activation_token_expiration_period => nil,
|
|
26
|
+
:@user_activation_mailer => nil,
|
|
27
|
+
:@activation_needed_email_method_name => :activation_needed_email,
|
|
28
|
+
:@activation_success_email_method_name => :activation_success_email,
|
|
29
|
+
:@prevent_non_active_users_to_login => true)
|
|
26
30
|
reset!
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
base.class_eval do
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
# don't setup activation if no password supplied - this user is created automatically
|
|
35
|
+
before_create :setup_activation, :if => Proc.new { |user| user.send(sorcery_config.password_attribute_name).present? }
|
|
36
|
+
# don't send activation needed email if no crypted password created - this user is external (OAuth etc.)
|
|
37
|
+
after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external?}
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
base.sorcery_config.after_config << :validate_mailer_defined
|
|
@@ -36,10 +42,22 @@ module Sorcery
|
|
|
36
42
|
base.sorcery_config.before_authenticate << :prevent_non_active_login
|
|
37
43
|
|
|
38
44
|
base.extend(ClassMethods)
|
|
45
|
+
base.send(:include, TemporaryToken)
|
|
39
46
|
base.send(:include, InstanceMethods)
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
module ClassMethods
|
|
50
|
+
# Find user by token, also checks for expiration.
|
|
51
|
+
# Returns the user if token found and is valid.
|
|
52
|
+
def load_from_activation_token(token)
|
|
53
|
+
token_attr_name = @sorcery_config.activation_token_attribute_name
|
|
54
|
+
token_expiration_date_attr = @sorcery_config.activation_token_expires_at_attribute_name
|
|
55
|
+
load_from_token(token, token_attr_name, token_expiration_date_attr)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
|
|
60
|
+
# This submodule requires the developer to define his own mailer class to be used by it.
|
|
43
61
|
def validate_mailer_defined
|
|
44
62
|
msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
|
|
45
63
|
raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
|
|
@@ -47,23 +65,26 @@ module Sorcery
|
|
|
47
65
|
end
|
|
48
66
|
|
|
49
67
|
module InstanceMethods
|
|
68
|
+
# clears activation code, sets the user as 'active' and optionaly sends a success email.
|
|
50
69
|
def activate!
|
|
51
70
|
config = sorcery_config
|
|
52
|
-
self.send(:"#{config.
|
|
71
|
+
self.send(:"#{config.activation_token_attribute_name}=", nil)
|
|
53
72
|
self.send(:"#{config.activation_state_attribute_name}=", "active")
|
|
54
|
-
send_activation_success_email!
|
|
73
|
+
send_activation_success_email! unless self.external?
|
|
55
74
|
save!(:validate => false) # don't run validations
|
|
56
75
|
end
|
|
57
|
-
|
|
76
|
+
|
|
58
77
|
protected
|
|
59
78
|
|
|
60
79
|
def setup_activation
|
|
61
80
|
config = sorcery_config
|
|
62
|
-
|
|
63
|
-
self.send(:"#{config.
|
|
81
|
+
generated_activation_token = generate_random_token
|
|
82
|
+
self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
|
|
64
83
|
self.send(:"#{config.activation_state_attribute_name}=", "pending")
|
|
84
|
+
self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.utc + config.activation_token_expiration_period) if config.activation_token_expiration_period
|
|
65
85
|
end
|
|
66
86
|
|
|
87
|
+
# called automatically after user initial creation.
|
|
67
88
|
def send_activation_needed_email!
|
|
68
89
|
generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil?
|
|
69
90
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Model
|
|
3
|
+
# This module encapsulates the logic for temporary token.
|
|
4
|
+
# A temporary token is created to identify a user in scenarios such as reseting password and activating the user by email.
|
|
5
|
+
module TemporaryToken
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.extend(ClassMethods)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
def load_from_token(token, token_attr_name, token_expiration_date_attr)
|
|
12
|
+
return nil if token.blank?
|
|
13
|
+
user = where("#{token_attr_name} = ?", token).first
|
|
14
|
+
if !user.blank? && !user.send(token_expiration_date_attr).nil?
|
|
15
|
+
return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
|
|
16
|
+
end
|
|
17
|
+
user
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/sorcery/model.rb
CHANGED
|
@@ -55,7 +55,8 @@ module Sorcery
|
|
|
55
55
|
_salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
|
|
56
56
|
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)
|
|
57
57
|
end
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
# Calls the configured encryption provider to compare the supplied password with the encrypted one.
|
|
59
60
|
def credentials_match?(crypted, *tokens)
|
|
60
61
|
return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
|
|
61
62
|
@sorcery_config.encryption_provider.matches?(crypted, *tokens)
|
|
@@ -78,13 +79,19 @@ module Sorcery
|
|
|
78
79
|
self.class.sorcery_config
|
|
79
80
|
end
|
|
80
81
|
|
|
82
|
+
# identifies whether this user is regular, i.e. we hold his credentials in our db,
|
|
83
|
+
# or that he is external, and his credentials are saved elsewhere (twitter/facebook etc.).
|
|
84
|
+
def external?
|
|
85
|
+
send(sorcery_config.crypted_password_attribute_name).nil?
|
|
86
|
+
end
|
|
87
|
+
|
|
81
88
|
protected
|
|
82
89
|
|
|
83
90
|
# creates new salt and saves it.
|
|
84
91
|
# encrypts password with salt and save it.
|
|
85
92
|
def encrypt_password
|
|
86
93
|
config = sorcery_config
|
|
87
|
-
new_salt = self.send(:"#{config.salt_attribute_name}=",
|
|
94
|
+
new_salt = self.send(:"#{config.salt_attribute_name}=", generate_random_token) if !config.salt_attribute_name.nil?
|
|
88
95
|
self.send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(self.send(config.password_attribute_name),new_salt))
|
|
89
96
|
end
|
|
90
97
|
|
|
@@ -104,7 +111,7 @@ module Sorcery
|
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
# Random code, used for salt and temporary tokens.
|
|
107
|
-
def
|
|
114
|
+
def generate_random_token
|
|
108
115
|
return Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
|
|
109
116
|
end
|
|
110
117
|
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module TestHelpers
|
|
3
|
+
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
|
|
4
|
+
|
|
5
|
+
def create_new_user(attributes_hash = nil)
|
|
6
|
+
user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
|
|
7
|
+
@user = User.new(user_attributes_hash)
|
|
8
|
+
@user.save!
|
|
9
|
+
@user
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create_new_external_user(provider, attributes_hash = nil)
|
|
13
|
+
user_attributes_hash = attributes_hash || {:username => 'gizmo', :authentications_attributes => [{:provider => provider, :uid => 123}]}
|
|
14
|
+
@user = User.new(user_attributes_hash)
|
|
15
|
+
@user.save!
|
|
16
|
+
@user
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def login_user(user = nil)
|
|
20
|
+
user ||= @user
|
|
21
|
+
subject.send(:login_user,user)
|
|
22
|
+
subject.send(:after_login!,user,[user.username,'secret'])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def logout_user
|
|
26
|
+
subject.send(:logout)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def clear_user_without_logout
|
|
30
|
+
subject.instance_variable_set(:@current_user,nil)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def sorcery_reload!(submodules = [], options = {})
|
|
34
|
+
reload_user_class
|
|
35
|
+
|
|
36
|
+
# return to no-module configuration
|
|
37
|
+
::Sorcery::Controller::Config.init!
|
|
38
|
+
::Sorcery::Controller::Config.reset!
|
|
39
|
+
|
|
40
|
+
# remove all plugin before_filters so they won't fail other tests.
|
|
41
|
+
# I don't like this way, but I didn't find another.
|
|
42
|
+
# hopefully it won't break until Rails 4.
|
|
43
|
+
ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
|
|
44
|
+
|
|
45
|
+
# configure
|
|
46
|
+
::Sorcery::Controller::Config.submodules = submodules
|
|
47
|
+
::Sorcery::Controller::Config.user_class = nil
|
|
48
|
+
ActionController::Base.send(:include,::Sorcery::Controller)
|
|
49
|
+
|
|
50
|
+
User.activate_sorcery! do |config|
|
|
51
|
+
options.each do |property,value|
|
|
52
|
+
config.send(:"#{property}=", value)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def sorcery_model_property_set(property, *values)
|
|
58
|
+
User.class_eval do
|
|
59
|
+
sorcery_config.send(:"#{property}=", *values)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def sorcery_controller_property_set(property, value)
|
|
64
|
+
ApplicationController.activate_sorcery! do |config|
|
|
65
|
+
config.send(:"#{property}=", value)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def sorcery_controller_oauth_property_set(provider, property, value)
|
|
70
|
+
ApplicationController.activate_sorcery! do |config|
|
|
71
|
+
config.send(provider).send(:"#{property}=", value)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# reload user class between specs
|
|
78
|
+
# so it will be possible to test the different submodules in isolation
|
|
79
|
+
def reload_user_class
|
|
80
|
+
Object.send(:remove_const,:User)
|
|
81
|
+
load 'user.rb'
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/sorcery.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
autoload :Model, 'sorcery/model'
|
|
3
3
|
module Model
|
|
4
|
+
autoload :TemporaryToken, 'sorcery/model/temporary_token'
|
|
4
5
|
module Submodules
|
|
5
6
|
autoload :UserActivation, 'sorcery/model/submodules/user_activation'
|
|
6
|
-
autoload :
|
|
7
|
+
autoload :ResetPassword, 'sorcery/model/submodules/reset_password'
|
|
7
8
|
autoload :RememberMe, 'sorcery/model/submodules/remember_me'
|
|
9
|
+
autoload :ActivityLogging, 'sorcery/model/submodules/activity_logging'
|
|
10
|
+
autoload :BruteForceProtection, 'sorcery/model/submodules/brute_force_protection'
|
|
11
|
+
autoload :Oauth, 'sorcery/model/submodules/oauth'
|
|
8
12
|
end
|
|
9
13
|
end
|
|
10
14
|
autoload :Controller, 'sorcery/controller'
|
|
@@ -14,6 +18,16 @@ module Sorcery
|
|
|
14
18
|
autoload :SessionTimeout, 'sorcery/controller/submodules/session_timeout'
|
|
15
19
|
autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
|
|
16
20
|
autoload :HttpBasicAuth, 'sorcery/controller/submodules/http_basic_auth'
|
|
21
|
+
autoload :ActivityLogging, 'sorcery/controller/submodules/activity_logging'
|
|
22
|
+
autoload :Oauth, 'sorcery/controller/submodules/oauth'
|
|
23
|
+
module Oauth
|
|
24
|
+
autoload :Oauth1, 'sorcery/controller/submodules/oauth/oauth1'
|
|
25
|
+
autoload :Oauth2, 'sorcery/controller/submodules/oauth/oauth2'
|
|
26
|
+
module Providers
|
|
27
|
+
autoload :Twitter, 'sorcery/controller/submodules/oauth/providers/twitter'
|
|
28
|
+
autoload :Facebook, 'sorcery/controller/submodules/oauth/providers/facebook'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
17
31
|
end
|
|
18
32
|
end
|
|
19
33
|
module CryptoProviders
|
|
@@ -24,6 +38,7 @@ module Sorcery
|
|
|
24
38
|
autoload :SHA256, 'sorcery/crypto_providers/sha256'
|
|
25
39
|
autoload :SHA512, 'sorcery/crypto_providers/sha512'
|
|
26
40
|
end
|
|
41
|
+
autoload :TestHelpers, 'sorcery/test_helpers'
|
|
27
42
|
|
|
28
43
|
require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
|
29
44
|
end
|
data/sorcery.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{sorcery}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.2.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 = %q{2011-
|
|
12
|
+
s.date = %q{2011-03-13}
|
|
13
13
|
s.description = %q{Provides common authentication needs such as signing in/out, activating by email and resetting password.}
|
|
14
14
|
s.email = %q{nbenari@gmail.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -25,11 +25,16 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
"README.rdoc",
|
|
26
26
|
"Rakefile",
|
|
27
27
|
"VERSION",
|
|
28
|
-
"features/support/env.rb",
|
|
29
28
|
"lib/sorcery.rb",
|
|
30
29
|
"lib/sorcery/controller.rb",
|
|
30
|
+
"lib/sorcery/controller/submodules/activity_logging.rb",
|
|
31
31
|
"lib/sorcery/controller/submodules/brute_force_protection.rb",
|
|
32
32
|
"lib/sorcery/controller/submodules/http_basic_auth.rb",
|
|
33
|
+
"lib/sorcery/controller/submodules/oauth.rb",
|
|
34
|
+
"lib/sorcery/controller/submodules/oauth/oauth1.rb",
|
|
35
|
+
"lib/sorcery/controller/submodules/oauth/oauth2.rb",
|
|
36
|
+
"lib/sorcery/controller/submodules/oauth/providers/facebook.rb",
|
|
37
|
+
"lib/sorcery/controller/submodules/oauth/providers/twitter.rb",
|
|
33
38
|
"lib/sorcery/controller/submodules/remember_me.rb",
|
|
34
39
|
"lib/sorcery/controller/submodules/session_timeout.rb",
|
|
35
40
|
"lib/sorcery/crypto_providers/aes256.rb",
|
|
@@ -40,23 +45,30 @@ Gem::Specification.new do |s|
|
|
|
40
45
|
"lib/sorcery/crypto_providers/sha512.rb",
|
|
41
46
|
"lib/sorcery/engine.rb",
|
|
42
47
|
"lib/sorcery/model.rb",
|
|
43
|
-
"lib/sorcery/model/submodules/
|
|
48
|
+
"lib/sorcery/model/submodules/activity_logging.rb",
|
|
49
|
+
"lib/sorcery/model/submodules/brute_force_protection.rb",
|
|
50
|
+
"lib/sorcery/model/submodules/oauth.rb",
|
|
44
51
|
"lib/sorcery/model/submodules/remember_me.rb",
|
|
52
|
+
"lib/sorcery/model/submodules/reset_password.rb",
|
|
45
53
|
"lib/sorcery/model/submodules/user_activation.rb",
|
|
54
|
+
"lib/sorcery/model/temporary_token.rb",
|
|
55
|
+
"lib/sorcery/test_helpers.rb",
|
|
46
56
|
"sorcery.gemspec",
|
|
47
57
|
"spec/Gemfile",
|
|
48
58
|
"spec/Gemfile.lock",
|
|
49
59
|
"spec/Rakefile",
|
|
50
60
|
"spec/rails3/.rspec",
|
|
51
|
-
"spec/rails3/Gemfile",
|
|
52
|
-
"spec/rails3/Gemfile.lock",
|
|
53
|
-
"spec/rails3/Rakefile",
|
|
54
61
|
"spec/rails3/app_root/.gitignore",
|
|
62
|
+
"spec/rails3/app_root/.rspec",
|
|
63
|
+
"spec/rails3/app_root/Gemfile",
|
|
64
|
+
"spec/rails3/app_root/Gemfile.lock",
|
|
55
65
|
"spec/rails3/app_root/README",
|
|
66
|
+
"spec/rails3/app_root/Rakefile",
|
|
56
67
|
"spec/rails3/app_root/Rakefile.unused",
|
|
57
68
|
"spec/rails3/app_root/app/controllers/application_controller.rb",
|
|
58
69
|
"spec/rails3/app_root/app/helpers/application_helper.rb",
|
|
59
70
|
"spec/rails3/app_root/app/mailers/sorcery_mailer.rb",
|
|
71
|
+
"spec/rails3/app_root/app/models/authentication.rb",
|
|
60
72
|
"spec/rails3/app_root/app/models/user.rb",
|
|
61
73
|
"spec/rails3/app_root/app/views/layouts/application.html.erb",
|
|
62
74
|
"spec/rails3/app_root/app/views/sorcery_mailer/activation_email.html.erb",
|
|
@@ -82,9 +94,12 @@ Gem::Specification.new do |s|
|
|
|
82
94
|
"spec/rails3/app_root/config/locales/en.yml",
|
|
83
95
|
"spec/rails3/app_root/config/routes.rb",
|
|
84
96
|
"spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb",
|
|
97
|
+
"spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb",
|
|
98
|
+
"spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb",
|
|
85
99
|
"spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb",
|
|
86
|
-
"spec/rails3/app_root/db/migrate/
|
|
100
|
+
"spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb",
|
|
87
101
|
"spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb",
|
|
102
|
+
"spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb",
|
|
88
103
|
"spec/rails3/app_root/db/schema.rb",
|
|
89
104
|
"spec/rails3/app_root/db/seeds.rb",
|
|
90
105
|
"spec/rails3/app_root/lib/tasks/.gitkeep",
|
|
@@ -103,33 +118,37 @@ Gem::Specification.new do |s|
|
|
|
103
118
|
"spec/rails3/app_root/public/robots.txt",
|
|
104
119
|
"spec/rails3/app_root/public/stylesheets/.gitkeep",
|
|
105
120
|
"spec/rails3/app_root/script/rails",
|
|
106
|
-
"spec/rails3/app_root/
|
|
107
|
-
"spec/rails3/app_root/
|
|
108
|
-
"spec/rails3/app_root/
|
|
109
|
-
"spec/rails3/app_root/
|
|
121
|
+
"spec/rails3/app_root/spec/controller_activity_logging_spec.rb",
|
|
122
|
+
"spec/rails3/app_root/spec/controller_brute_force_protection_spec.rb",
|
|
123
|
+
"spec/rails3/app_root/spec/controller_http_basic_auth_spec.rb",
|
|
124
|
+
"spec/rails3/app_root/spec/controller_oauth2_spec.rb",
|
|
125
|
+
"spec/rails3/app_root/spec/controller_oauth_spec.rb",
|
|
126
|
+
"spec/rails3/app_root/spec/controller_remember_me_spec.rb",
|
|
127
|
+
"spec/rails3/app_root/spec/controller_session_timeout_spec.rb",
|
|
128
|
+
"spec/rails3/app_root/spec/controller_spec.rb",
|
|
129
|
+
"spec/rails3/app_root/spec/spec_helper.orig.rb",
|
|
130
|
+
"spec/rails3/app_root/spec/spec_helper.rb",
|
|
131
|
+
"spec/rails3/app_root/spec/user_activation_spec.rb",
|
|
132
|
+
"spec/rails3/app_root/spec/user_activity_logging_spec.rb",
|
|
133
|
+
"spec/rails3/app_root/spec/user_brute_force_protection_spec.rb",
|
|
134
|
+
"spec/rails3/app_root/spec/user_oauth_spec.rb",
|
|
135
|
+
"spec/rails3/app_root/spec/user_remember_me_spec.rb",
|
|
136
|
+
"spec/rails3/app_root/spec/user_reset_password_spec.rb",
|
|
137
|
+
"spec/rails3/app_root/spec/user_spec.rb",
|
|
110
138
|
"spec/rails3/app_root/vendor/plugins/.gitkeep",
|
|
111
|
-
"spec/rails3/controller_brute_force_protection_spec.rb",
|
|
112
|
-
"spec/rails3/controller_http_basic_auth_spec.rb",
|
|
113
|
-
"spec/rails3/controller_remember_me_spec.rb",
|
|
114
|
-
"spec/rails3/controller_session_timeout_spec.rb",
|
|
115
|
-
"spec/rails3/controller_spec.rb",
|
|
116
|
-
"spec/rails3/spec_helper.rb",
|
|
117
|
-
"spec/rails3/user_activation_spec.rb",
|
|
118
|
-
"spec/rails3/user_password_reset_spec.rb",
|
|
119
|
-
"spec/rails3/user_remember_me_spec.rb",
|
|
120
|
-
"spec/rails3/user_spec.rb",
|
|
121
139
|
"spec/sorcery_crypto_providers_spec.rb",
|
|
122
140
|
"spec/spec_helper.rb"
|
|
123
141
|
]
|
|
124
142
|
s.homepage = %q{http://github.com/NoamB/sorcery}
|
|
125
143
|
s.licenses = ["MIT"]
|
|
126
144
|
s.require_paths = ["lib"]
|
|
127
|
-
s.rubygems_version = %q{1.
|
|
145
|
+
s.rubygems_version = %q{1.6.2}
|
|
128
146
|
s.summary = %q{Magical authentication for Rails 3 applications}
|
|
129
147
|
s.test_files = [
|
|
130
148
|
"spec/rails3/app_root/app/controllers/application_controller.rb",
|
|
131
149
|
"spec/rails3/app_root/app/helpers/application_helper.rb",
|
|
132
150
|
"spec/rails3/app_root/app/mailers/sorcery_mailer.rb",
|
|
151
|
+
"spec/rails3/app_root/app/models/authentication.rb",
|
|
133
152
|
"spec/rails3/app_root/app/models/user.rb",
|
|
134
153
|
"spec/rails3/app_root/config/application.rb",
|
|
135
154
|
"spec/rails3/app_root/config/boot.rb",
|
|
@@ -145,24 +164,31 @@ Gem::Specification.new do |s|
|
|
|
145
164
|
"spec/rails3/app_root/config/initializers/session_store.rb",
|
|
146
165
|
"spec/rails3/app_root/config/routes.rb",
|
|
147
166
|
"spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb",
|
|
167
|
+
"spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb",
|
|
168
|
+
"spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb",
|
|
148
169
|
"spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb",
|
|
149
|
-
"spec/rails3/app_root/db/migrate/
|
|
170
|
+
"spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb",
|
|
150
171
|
"spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb",
|
|
172
|
+
"spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb",
|
|
151
173
|
"spec/rails3/app_root/db/schema.rb",
|
|
152
174
|
"spec/rails3/app_root/db/seeds.rb",
|
|
153
|
-
"spec/rails3/app_root/
|
|
154
|
-
"spec/rails3/app_root/
|
|
155
|
-
"spec/rails3/app_root/
|
|
156
|
-
"spec/rails3/
|
|
157
|
-
"spec/rails3/
|
|
158
|
-
"spec/rails3/controller_remember_me_spec.rb",
|
|
159
|
-
"spec/rails3/controller_session_timeout_spec.rb",
|
|
160
|
-
"spec/rails3/controller_spec.rb",
|
|
161
|
-
"spec/rails3/spec_helper.rb",
|
|
162
|
-
"spec/rails3/
|
|
163
|
-
"spec/rails3/
|
|
164
|
-
"spec/rails3/
|
|
165
|
-
"spec/rails3/
|
|
175
|
+
"spec/rails3/app_root/spec/controller_activity_logging_spec.rb",
|
|
176
|
+
"spec/rails3/app_root/spec/controller_brute_force_protection_spec.rb",
|
|
177
|
+
"spec/rails3/app_root/spec/controller_http_basic_auth_spec.rb",
|
|
178
|
+
"spec/rails3/app_root/spec/controller_oauth2_spec.rb",
|
|
179
|
+
"spec/rails3/app_root/spec/controller_oauth_spec.rb",
|
|
180
|
+
"spec/rails3/app_root/spec/controller_remember_me_spec.rb",
|
|
181
|
+
"spec/rails3/app_root/spec/controller_session_timeout_spec.rb",
|
|
182
|
+
"spec/rails3/app_root/spec/controller_spec.rb",
|
|
183
|
+
"spec/rails3/app_root/spec/spec_helper.orig.rb",
|
|
184
|
+
"spec/rails3/app_root/spec/spec_helper.rb",
|
|
185
|
+
"spec/rails3/app_root/spec/user_activation_spec.rb",
|
|
186
|
+
"spec/rails3/app_root/spec/user_activity_logging_spec.rb",
|
|
187
|
+
"spec/rails3/app_root/spec/user_brute_force_protection_spec.rb",
|
|
188
|
+
"spec/rails3/app_root/spec/user_oauth_spec.rb",
|
|
189
|
+
"spec/rails3/app_root/spec/user_remember_me_spec.rb",
|
|
190
|
+
"spec/rails3/app_root/spec/user_reset_password_spec.rb",
|
|
191
|
+
"spec/rails3/app_root/spec/user_spec.rb",
|
|
166
192
|
"spec/sorcery_crypto_providers_spec.rb",
|
|
167
193
|
"spec/spec_helper.rb"
|
|
168
194
|
]
|
|
@@ -171,39 +197,54 @@ Gem::Specification.new do |s|
|
|
|
171
197
|
s.specification_version = 3
|
|
172
198
|
|
|
173
199
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
174
|
-
s.
|
|
200
|
+
s.add_runtime_dependency(%q<rails>, [">= 3.0.0"])
|
|
201
|
+
s.add_runtime_dependency(%q<json>, [">= 1.5.1"])
|
|
202
|
+
s.add_runtime_dependency(%q<oauth>, [">= 0.4.4"])
|
|
203
|
+
s.add_runtime_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
175
204
|
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
176
205
|
s.add_development_dependency(%q<rspec-rails>, [">= 0"])
|
|
177
206
|
s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
|
|
178
207
|
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
|
179
208
|
s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
|
|
180
|
-
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
|
181
209
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
182
210
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
183
211
|
s.add_development_dependency(%q<simplecov>, [">= 0.3.8"])
|
|
212
|
+
s.add_runtime_dependency(%q<bcrypt-ruby>, ["~> 2.1.4"])
|
|
213
|
+
s.add_runtime_dependency(%q<oauth>, [">= 0.4.4"])
|
|
214
|
+
s.add_runtime_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
184
215
|
else
|
|
185
|
-
s.add_dependency(%q<rails>, ["
|
|
216
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
|
217
|
+
s.add_dependency(%q<json>, [">= 1.5.1"])
|
|
218
|
+
s.add_dependency(%q<oauth>, [">= 0.4.4"])
|
|
219
|
+
s.add_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
186
220
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
187
221
|
s.add_dependency(%q<rspec-rails>, [">= 0"])
|
|
188
222
|
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
|
189
223
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
|
190
224
|
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
|
191
|
-
s.add_dependency(%q<cucumber>, [">= 0"])
|
|
192
225
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
193
226
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
194
227
|
s.add_dependency(%q<simplecov>, [">= 0.3.8"])
|
|
228
|
+
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.4"])
|
|
229
|
+
s.add_dependency(%q<oauth>, [">= 0.4.4"])
|
|
230
|
+
s.add_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
195
231
|
end
|
|
196
232
|
else
|
|
197
|
-
s.add_dependency(%q<rails>, ["
|
|
233
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
|
234
|
+
s.add_dependency(%q<json>, [">= 1.5.1"])
|
|
235
|
+
s.add_dependency(%q<oauth>, [">= 0.4.4"])
|
|
236
|
+
s.add_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
198
237
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
199
238
|
s.add_dependency(%q<rspec-rails>, [">= 0"])
|
|
200
239
|
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
|
201
240
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
|
202
241
|
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
|
203
|
-
s.add_dependency(%q<cucumber>, [">= 0"])
|
|
204
242
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
205
243
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
206
244
|
s.add_dependency(%q<simplecov>, [">= 0.3.8"])
|
|
245
|
+
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.4"])
|
|
246
|
+
s.add_dependency(%q<oauth>, [">= 0.4.4"])
|
|
247
|
+
s.add_dependency(%q<oauth2>, [">= 0.1.1"])
|
|
207
248
|
end
|
|
208
249
|
end
|
|
209
250
|
|
data/spec/Gemfile
CHANGED
|
@@ -2,8 +2,9 @@ source 'http://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
gem "rails", '3.0.3'
|
|
4
4
|
gem 'bcrypt-ruby', :require => 'bcrypt'
|
|
5
|
-
gem "sorcery", '0.1.
|
|
6
|
-
|
|
5
|
+
gem "sorcery", '0.1.4', :path => '../../../'
|
|
6
|
+
gem 'oauth', ">= 0.4.4"
|
|
7
|
+
gem 'oauth2', ">= 0.1.1"
|
|
7
8
|
group :development do
|
|
8
9
|
gem 'rspec'
|
|
9
10
|
gem 'ruby-debug19'
|