sorcery 0.1.4 → 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.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- data/Gemfile +4 -2
- data/Gemfile.lock +16 -13
- data/README.rdoc +28 -27
- data/Rakefile +5 -0
- data/VERSION +1 -1
- data/lib/sorcery.rb +12 -0
- data/lib/sorcery/controller.rb +29 -17
- data/lib/sorcery/controller/submodules/activity_logging.rb +20 -7
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +9 -2
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +8 -3
- data/lib/sorcery/controller/submodules/oauth.rb +95 -0
- 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/remember_me.rb +14 -5
- data/lib/sorcery/controller/submodules/session_timeout.rb +6 -1
- data/lib/sorcery/engine.rb +9 -2
- data/lib/sorcery/model.rb +10 -3
- data/lib/sorcery/model/submodules/activity_logging.rb +12 -7
- data/lib/sorcery/model/submodules/brute_force_protection.rb +11 -4
- data/lib/sorcery/model/submodules/oauth.rb +53 -0
- data/lib/sorcery/model/submodules/remember_me.rb +5 -3
- data/lib/sorcery/model/submodules/reset_password.rb +16 -13
- data/lib/sorcery/model/submodules/user_activation.rb +38 -19
- data/lib/sorcery/model/temporary_token.rb +22 -0
- data/lib/sorcery/test_helpers.rb +84 -0
- data/sorcery.gemspec +69 -40
- 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/{Rakefile → app_root/Rakefile} +0 -0
- data/spec/rails3/app_root/app/controllers/application_controller.rb +42 -1
- 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/core/20101224223620_create_users.rb +4 -4
- data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
- data/spec/rails3/{controller_activity_logging_spec.rb → app_root/spec/controller_activity_logging_spec.rb} +13 -13
- data/spec/rails3/{controller_brute_force_protection_spec.rb → app_root/spec/controller_brute_force_protection_spec.rb} +16 -6
- data/spec/rails3/{controller_http_basic_auth_spec.rb → app_root/spec/controller_http_basic_auth_spec.rb} +3 -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} +4 -4
- data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +20 -13
- 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/{user_activity_logging_spec.rb → app_root/spec/user_activity_logging_spec.rb} +4 -4
- data/spec/rails3/{user_brute_force_protection_spec.rb → app_root/spec/user_brute_force_protection_spec.rb} +7 -7
- 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/{user_reset_password_spec.rb → app_root/spec/user_reset_password_spec.rb} +21 -41
- data/spec/rails3/{user_spec.rb → app_root/spec/user_spec.rb} +68 -38
- metadata +127 -58
- 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/spec_helper.rb +0 -135
@@ -1,20 +1,25 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module Model
|
3
3
|
module Submodules
|
4
|
+
# This submodule keeps track of events such as login, logout, and last activity time, per user.
|
5
|
+
# It helps in estimating which users are active now in the site.
|
6
|
+
# This cannot be determined absolutely because a user might be reading a page without clicking anything for a while.
|
7
|
+
|
8
|
+
# This is the model part of the submodule, which provides configuration options.
|
4
9
|
module ActivityLogging
|
5
10
|
def self.included(base)
|
6
11
|
base.extend(ClassMethods)
|
7
12
|
base.sorcery_config.class_eval do
|
8
|
-
attr_accessor :last_login_at_attribute_name,
|
9
|
-
:last_logout_at_attribute_name,
|
10
|
-
:last_activity_at_attribute_name,
|
13
|
+
attr_accessor :last_login_at_attribute_name, # last login attribute name.
|
14
|
+
:last_logout_at_attribute_name, # last logout attribute name.
|
15
|
+
:last_activity_at_attribute_name, # last activity attribute name.
|
11
16
|
:activity_timeout # how long since last activity is the user defined logged out?
|
12
17
|
end
|
13
18
|
|
14
19
|
base.sorcery_config.instance_eval do
|
15
|
-
@defaults.merge!(:@last_login_at_attribute_name
|
16
|
-
:@last_logout_at_attribute_name
|
17
|
-
:@last_activity_at_attribute_name
|
20
|
+
@defaults.merge!(:@last_login_at_attribute_name => :last_login_at,
|
21
|
+
:@last_logout_at_attribute_name => :last_logout_at,
|
22
|
+
:@last_activity_at_attribute_name => :last_activity_at,
|
18
23
|
:@activity_timeout => 10.minutes)
|
19
24
|
reset!
|
20
25
|
end
|
@@ -22,7 +27,7 @@ module Sorcery
|
|
22
27
|
|
23
28
|
module ClassMethods
|
24
29
|
# get all users with last_activity within timeout
|
25
|
-
def
|
30
|
+
def current_users
|
26
31
|
config = sorcery_config
|
27
32
|
where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
|
28
33
|
.where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
|
@@ -1,19 +1,21 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module Model
|
3
3
|
module Submodules
|
4
|
+
# This module helps protect user accounts by locking them down after too many failed attemps to login were detected.
|
5
|
+
# This is the model part of the submodule which provides configuration options and methods for locking and unlocking the user.
|
4
6
|
module BruteForceProtection
|
5
7
|
def self.included(base)
|
6
8
|
base.sorcery_config.class_eval do
|
7
9
|
attr_accessor :failed_logins_count_attribute_name, # failed logins attribute name.
|
8
10
|
:lock_expires_at_attribute_name, # this field indicates whether user is banned and when it will be active again.
|
9
|
-
:
|
11
|
+
:consecutive_login_retries_amount_limit, # how many failed logins allowed.
|
10
12
|
:login_lock_time_period # how long the user should be banned. in seconds. 0 for permanent.
|
11
13
|
end
|
12
14
|
|
13
15
|
base.sorcery_config.instance_eval do
|
14
16
|
@defaults.merge!(:@failed_logins_count_attribute_name => :failed_logins_count,
|
15
17
|
:@lock_expires_at_attribute_name => :lock_expires_at,
|
16
|
-
:@
|
18
|
+
:@consecutive_login_retries_amount_limit => 50,
|
17
19
|
:@login_lock_time_period => 3600)
|
18
20
|
reset!
|
19
21
|
end
|
@@ -33,11 +35,14 @@ module Sorcery
|
|
33
35
|
end
|
34
36
|
|
35
37
|
module InstanceMethods
|
38
|
+
# Called by the controller to increment the failed logins counter.
|
39
|
+
# Calls 'lock!' if login retries limit was reached.
|
36
40
|
def register_failed_login!
|
37
41
|
config = sorcery_config
|
42
|
+
return if !unlocked?
|
38
43
|
self.increment(config.failed_logins_count_attribute_name)
|
39
44
|
save!
|
40
|
-
self.lock! if self.send(config.failed_logins_count_attribute_name) >= config.
|
45
|
+
self.lock! if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
|
41
46
|
end
|
42
47
|
|
43
48
|
protected
|
@@ -58,9 +63,11 @@ module Sorcery
|
|
58
63
|
self.send(config.lock_expires_at_attribute_name).nil?
|
59
64
|
end
|
60
65
|
|
66
|
+
# Prevents a locked user from logging in, and unlocks users that expired their lock time.
|
67
|
+
# Runs as a hook before authenticate.
|
61
68
|
def prevent_locked_user_login
|
62
69
|
config = sorcery_config
|
63
|
-
if !self.unlocked?
|
70
|
+
if !self.unlocked? && config.login_lock_time_period != 0
|
64
71
|
self.unlock! if self.send(config.lock_expires_at_attribute_name) <= Time.now.utc
|
65
72
|
end
|
66
73
|
unlocked?
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module Model
|
3
|
+
module Submodules
|
4
|
+
# This submodule helps you login users from OAuth providers such as Twitter.
|
5
|
+
# This is the model part which handles finding the user using access tokens.
|
6
|
+
# For the controller options see Sorcery::Controller::Oauth.
|
7
|
+
#
|
8
|
+
# Socery assumes (read: requires) you will create external users in the same table where you keep your regular users,
|
9
|
+
# but that you will have a separate table for keeping their external authentication data,
|
10
|
+
# and that that separate table has a few rows for each user, facebook and twitter for example (a one-to-many relationship).
|
11
|
+
#
|
12
|
+
# External users will have a null crypted_password field, since we do not hold their password.
|
13
|
+
# They will not be sent activation emails on creation.
|
14
|
+
module Oauth
|
15
|
+
def self.included(base)
|
16
|
+
base.sorcery_config.class_eval do
|
17
|
+
attr_accessor :authentications_class,
|
18
|
+
:authentications_user_id_attribute_name,
|
19
|
+
:provider_attribute_name,
|
20
|
+
:provider_uid_attribute_name
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
base.sorcery_config.instance_eval do
|
25
|
+
@defaults.merge!(:@authentications_class => Sorcery::Controller::Config.authentications_class,
|
26
|
+
:@authentications_user_id_attribute_name => :user_id,
|
27
|
+
:@provider_attribute_name => :provider,
|
28
|
+
:@provider_uid_attribute_name => :uid)
|
29
|
+
|
30
|
+
reset!
|
31
|
+
end
|
32
|
+
|
33
|
+
base.send(:include, InstanceMethods)
|
34
|
+
base.extend(ClassMethods)
|
35
|
+
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
# takes a provider and uid and finds a user by them.
|
39
|
+
def load_from_provider(provider,uid)
|
40
|
+
config = sorcery_config
|
41
|
+
authentication = config.authentications_class.find_by_provider_and_uid(provider, uid)
|
42
|
+
user = find(authentication.send(config.authentications_user_id_attribute_name)) if authentication
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module InstanceMethods
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module Model
|
3
3
|
module Submodules
|
4
|
+
# The Remember Me submodule takes care of setting the user's cookie so that he will be automatically logged in to the site on every visit,
|
5
|
+
# until the cookie expires.
|
4
6
|
module RememberMe
|
5
7
|
def self.included(base)
|
6
8
|
base.sorcery_config.class_eval do
|
@@ -22,15 +24,15 @@ module Sorcery
|
|
22
24
|
end
|
23
25
|
|
24
26
|
module InstanceMethods
|
25
|
-
# You shouldn't really use this one - it's called by the controller's 'remember_me!' method.
|
27
|
+
# You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
|
26
28
|
def remember_me!
|
27
29
|
config = sorcery_config
|
28
|
-
self.send(:"#{config.remember_me_token_attribute_name}=",
|
30
|
+
self.send(:"#{config.remember_me_token_attribute_name}=", generate_random_token)
|
29
31
|
self.send(:"#{config.remember_me_token_expires_at_attribute_name}=", Time.now + config.remember_me_for)
|
30
32
|
self.save!(:validate => false)
|
31
33
|
end
|
32
34
|
|
33
|
-
# You shouldn't really use this one - it's called by the controller's 'forget_me!' method.
|
35
|
+
# You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method.
|
34
36
|
def forget_me!
|
35
37
|
config = sorcery_config
|
36
38
|
self.send(:"#{config.remember_me_token_attribute_name}=", nil)
|
@@ -2,6 +2,12 @@ module Sorcery
|
|
2
2
|
module Model
|
3
3
|
module Submodules
|
4
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.
|
5
11
|
module ResetPassword
|
6
12
|
def self.included(base)
|
7
13
|
base.sorcery_config.class_eval do
|
@@ -30,22 +36,22 @@ module Sorcery
|
|
30
36
|
base.sorcery_config.after_config << :validate_mailer_defined
|
31
37
|
|
32
38
|
base.extend(ClassMethods)
|
39
|
+
base.send(:include, TemporaryToken)
|
33
40
|
base.send(:include, InstanceMethods)
|
34
41
|
end
|
35
42
|
|
36
43
|
module ClassMethods
|
37
|
-
|
44
|
+
# Find user by token, also checks for expiration.
|
45
|
+
# Returns the user if token found and is valid.
|
38
46
|
def load_from_reset_password_token(token)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
return user.reset_password_token_valid? ? user : nil
|
43
|
-
end
|
44
|
-
user
|
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)
|
45
50
|
end
|
46
51
|
|
47
52
|
protected
|
48
53
|
|
54
|
+
# This submodule requires the developer to define his own mailer class to be used by it.
|
49
55
|
def validate_mailer_defined
|
50
56
|
msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)."
|
51
57
|
raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
|
@@ -59,7 +65,7 @@ module Sorcery
|
|
59
65
|
config = sorcery_config
|
60
66
|
# hammering protection
|
61
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
|
62
|
-
self.send(:"#{config.reset_password_token_attribute_name}=",
|
68
|
+
self.send(:"#{config.reset_password_token_attribute_name}=", generate_random_token)
|
63
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
|
64
70
|
self.send(:"#{config.reset_password_email_sent_at_attribute_name}=", Time.now.utc)
|
65
71
|
self.class.transaction do
|
@@ -68,18 +74,15 @@ module Sorcery
|
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
77
|
+
# Clears token and tries to update the new password for the user.
|
71
78
|
def reset_password!(params)
|
72
79
|
clear_reset_password_token
|
73
80
|
update_attributes(params)
|
74
81
|
end
|
75
|
-
|
76
|
-
def reset_password_token_valid?
|
77
|
-
config = sorcery_config
|
78
|
-
config.reset_password_expiration_period ? Time.now.utc < self.send(config.reset_password_token_expires_at_attribute_name) : true
|
79
|
-
end
|
80
82
|
|
81
83
|
protected
|
82
84
|
|
85
|
+
# Clears the token.
|
83
86
|
def clear_reset_password_token
|
84
87
|
config = sorcery_config
|
85
88
|
self.send(:"#{config.reset_password_token_attribute_name}=", nil)
|
@@ -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,12 +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
|
+
|
43
58
|
protected
|
44
59
|
|
60
|
+
# This submodule requires the developer to define his own mailer class to be used by it.
|
45
61
|
def validate_mailer_defined
|
46
62
|
msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
|
47
63
|
raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
|
@@ -49,23 +65,26 @@ module Sorcery
|
|
49
65
|
end
|
50
66
|
|
51
67
|
module InstanceMethods
|
68
|
+
# clears activation code, sets the user as 'active' and optionaly sends a success email.
|
52
69
|
def activate!
|
53
70
|
config = sorcery_config
|
54
|
-
self.send(:"#{config.
|
71
|
+
self.send(:"#{config.activation_token_attribute_name}=", nil)
|
55
72
|
self.send(:"#{config.activation_state_attribute_name}=", "active")
|
56
|
-
send_activation_success_email!
|
73
|
+
send_activation_success_email! unless self.external?
|
57
74
|
save!(:validate => false) # don't run validations
|
58
75
|
end
|
59
|
-
|
76
|
+
|
60
77
|
protected
|
61
78
|
|
62
79
|
def setup_activation
|
63
80
|
config = sorcery_config
|
64
|
-
|
65
|
-
self.send(:"#{config.
|
81
|
+
generated_activation_token = generate_random_token
|
82
|
+
self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
|
66
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
|
67
85
|
end
|
68
86
|
|
87
|
+
# called automatically after user initial creation.
|
69
88
|
def send_activation_needed_email!
|
70
89
|
generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil?
|
71
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
|
@@ -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
|