sorcery 0.5.3 → 0.5.21
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/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/sorcery/controller.rb +3 -5
- data/lib/sorcery/controller/submodules/activity_logging.rb +6 -10
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +3 -6
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +5 -10
- data/lib/sorcery/controller/submodules/remember_me.rb +4 -13
- data/lib/sorcery/controller/submodules/session_timeout.rb +1 -3
- data/lib/sorcery/crypto_providers/aes256.rb +5 -8
- data/lib/sorcery/crypto_providers/bcrypt.rb +6 -12
- data/lib/sorcery/crypto_providers/sha256.rb +1 -2
- data/lib/sorcery/crypto_providers/sha512.rb +1 -2
- data/lib/sorcery/initializers/initializer.rb +36 -125
- data/lib/sorcery/model.rb +15 -28
- data/lib/sorcery/model/adapters/active_record.rb +2 -2
- data/lib/sorcery/model/adapters/mongoid.rb +2 -2
- data/lib/sorcery/model/submodules/activity_logging.rb +6 -7
- data/lib/sorcery/model/submodules/brute_force_protection.rb +6 -10
- data/lib/sorcery/model/submodules/external.rb +2 -4
- data/lib/sorcery/model/submodules/remember_me.rb +3 -4
- data/lib/sorcery/model/submodules/reset_password.rb +8 -16
- data/lib/sorcery/model/submodules/user_activation.rb +10 -23
- data/lib/sorcery/model/temporary_token.rb +2 -3
- data/lib/sorcery/test_helpers/internal.rb +1 -2
- data/lib/sorcery/test_helpers/internal/rails.rb +1 -5
- data/sorcery.gemspec +2 -16
- data/spec/Gemfile.lock +1 -1
- data/spec/rails3/Gemfile.lock +1 -1
- data/spec/rails3/spec/user_activation_spec.rb +168 -2
- data/spec/rails3/spec/user_activity_logging_spec.rb +30 -2
- data/spec/rails3/spec/user_brute_force_protection_spec.rb +35 -2
- data/spec/rails3/spec/user_oauth_spec.rb +26 -2
- data/spec/rails3/spec/user_remember_me_spec.rb +45 -2
- data/spec/rails3/spec/user_reset_password_spec.rb +168 -3
- data/spec/rails3/spec/user_spec.rb +283 -3
- data/spec/rails3_mongoid/Gemfile.lock +1 -1
- data/spec/rails3_mongoid/app/models/authentication.rb +3 -3
- data/spec/rails3_mongoid/spec/user_activation_spec.rb +171 -2
- data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +25 -2
- data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +35 -2
- data/spec/rails3_mongoid/spec/user_oauth_spec.rb +28 -2
- data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +45 -2
- data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +176 -2
- data/spec/rails3_mongoid/spec/user_spec.rb +285 -3
- data/spec/sinatra/Gemfile.lock +1 -1
- data/spec/sinatra_modular/Gemfile.lock +1 -1
- metadata +2 -16
- data/spec/shared_examples/user_activation_shared_examples.rb +0 -173
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +0 -27
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +0 -37
- data/spec/shared_examples/user_oauth_shared_examples.rb +0 -30
- data/spec/shared_examples/user_remember_me_shared_examples.rb +0 -47
- data/spec/shared_examples/user_reset_password_shared_examples.rb +0 -177
- data/spec/shared_examples/user_shared_examples.rb +0 -292
data/lib/sorcery/model.rb
CHANGED
@@ -3,8 +3,7 @@ module Sorcery
|
|
3
3
|
# It should be included into the ORM base class.
|
4
4
|
# In the case of Rails this is usually ActiveRecord (actually, in that case, the plugin does this automatically).
|
5
5
|
#
|
6
|
-
# When included it defines a single method: 'activate_sorcery!' which when called adds the other capabilities
|
7
|
-
# to the class.
|
6
|
+
# When included it defines a single method: 'activate_sorcery!' which when called adds the other capabilities to the class.
|
8
7
|
# This method is also the place to configure the plugin in the Model layer.
|
9
8
|
module Model
|
10
9
|
def self.included(klass)
|
@@ -21,8 +20,7 @@ module Sorcery
|
|
21
20
|
begin
|
22
21
|
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
23
22
|
rescue NameError
|
24
|
-
# don't stop on a missing submodule. Needed because some submodules are only defined
|
25
|
-
# in the controller side.
|
23
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined in the controller side.
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
@@ -32,10 +30,11 @@ module Sorcery
|
|
32
30
|
|
33
31
|
# Mongoid support
|
34
32
|
self.class_eval do
|
35
|
-
field sorcery_config.username_attribute_name,
|
36
|
-
field sorcery_config.
|
37
|
-
field sorcery_config.
|
38
|
-
field sorcery_config.
|
33
|
+
field sorcery_config.username_attribute_name, type: String
|
34
|
+
#field sorcery_config.password_attribute_name, type: String
|
35
|
+
field sorcery_config.email_attribute_name, type: String unless sorcery_config.username_attribute_name == sorcery_config.email_attribute_name
|
36
|
+
field sorcery_config.crypted_password_attribute_name, type: String
|
37
|
+
field sorcery_config.salt_attribute_name, type: String
|
39
38
|
end if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
|
40
39
|
|
41
40
|
# add virtual password accessor and ORM callbacks
|
@@ -148,38 +147,26 @@ module Sorcery
|
|
148
147
|
end
|
149
148
|
|
150
149
|
# Each class which calls 'activate_sorcery!' receives an instance of this class.
|
151
|
-
# Every submodule which gets loaded may add accessors to this class so that all
|
152
|
-
# options will be configured from a single place.
|
150
|
+
# Every submodule which gets loaded may add accessors to this class so that all options will be configured from a single place.
|
153
151
|
class Config
|
154
152
|
|
155
|
-
attr_accessor :username_attribute_name, # change default username attribute, for example, to use :email
|
156
|
-
|
157
|
-
|
158
|
-
:password_attribute_name, # change *virtual* password attribute, the one which is used
|
159
|
-
# until an encrypted one is generated.
|
160
|
-
|
153
|
+
attr_accessor :username_attribute_name, # change default username attribute, for example, to use :email as the login.
|
154
|
+
:password_attribute_name, # change *virtual* password attribute, the one which is used until an encrypted one is generated.
|
161
155
|
:email_attribute_name, # change default email attribute.
|
162
156
|
:crypted_password_attribute_name, # change default crypted_password attribute.
|
163
157
|
:salt_join_token, # what pattern to use to join the password with the salt
|
164
158
|
:salt_attribute_name, # change default salt attribute.
|
165
159
|
:stretches, # how many times to apply encryption to the password.
|
166
|
-
:encryption_key, # encryption key used to encrypt reversible encryptions such as
|
167
|
-
|
168
|
-
|
169
|
-
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for
|
170
|
-
# ActiveRecord's STI.
|
160
|
+
:encryption_key, # encryption key used to encrypt reversible encryptions such as AES256.
|
161
|
+
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
|
171
162
|
|
172
163
|
:submodules, # configured in config/application.rb
|
173
|
-
:before_authenticate, # an array of method names to call before authentication
|
174
|
-
|
175
|
-
|
176
|
-
:after_config # an array of method names to call after configuration by user.
|
177
|
-
# used internally.
|
164
|
+
:before_authenticate, # an array of method names to call before authentication completes. used internally.
|
165
|
+
:after_config # an array of method names to call after configuration by user. used internally.
|
178
166
|
|
179
167
|
attr_reader :encryption_provider, # change default encryption_provider.
|
180
168
|
:custom_encryption_provider, # use an external encryption class.
|
181
|
-
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
|
182
|
-
# for available options.
|
169
|
+
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below for available options.
|
183
170
|
|
184
171
|
def initialize
|
185
172
|
@defaults = {
|
@@ -11,7 +11,7 @@ module Sorcery
|
|
11
11
|
where("#{@sorcery_config.username_attribute_name} = ?", credentials[0]).first
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def find_by_token(token_attr_name, token)
|
15
15
|
where("#{token_attr_name} = ?", token).first
|
16
16
|
end
|
17
17
|
|
@@ -25,4 +25,4 @@ module Sorcery
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
end
|
28
|
+
end
|
@@ -43,7 +43,7 @@ module Sorcery
|
|
43
43
|
tap(&blk)
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
46
|
+
def find_by_token(token_attr_name, token)
|
47
47
|
where(token_attr_name => token).first
|
48
48
|
end
|
49
49
|
|
@@ -61,4 +61,4 @@ module Sorcery
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -3,8 +3,8 @@ module Sorcery
|
|
3
3
|
module Submodules
|
4
4
|
# This submodule keeps track of events such as login, logout, and last activity time, per user.
|
5
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
|
7
|
-
|
6
|
+
# This cannot be determined absolutely because a user might be reading a page without clicking anything for a while.
|
7
|
+
|
8
8
|
# This is the model part of the submodule, which provides configuration options.
|
9
9
|
module ActivityLogging
|
10
10
|
def self.included(base)
|
@@ -14,8 +14,7 @@ module Sorcery
|
|
14
14
|
attr_accessor :last_login_at_attribute_name, # last login attribute name.
|
15
15
|
:last_logout_at_attribute_name, # last logout attribute name.
|
16
16
|
:last_activity_at_attribute_name, # last activity attribute name.
|
17
|
-
:activity_timeout # how long since last activity is
|
18
|
-
#the user defined logged out?
|
17
|
+
:activity_timeout # how long since last activity is the user defined logged out?
|
19
18
|
end
|
20
19
|
|
21
20
|
base.sorcery_config.instance_eval do
|
@@ -39,9 +38,9 @@ module Sorcery
|
|
39
38
|
protected
|
40
39
|
|
41
40
|
def define_activity_logging_mongoid_fields
|
42
|
-
field sorcery_config.last_login_at_attribute_name,
|
43
|
-
field sorcery_config.last_logout_at_attribute_name,
|
44
|
-
field sorcery_config.last_activity_at_attribute_name, :
|
41
|
+
field sorcery_config.last_login_at_attribute_name, type: DateTime
|
42
|
+
field sorcery_config.last_logout_at_attribute_name, type: DateTime
|
43
|
+
field sorcery_config.last_activity_at_attribute_name, type: DateTime
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
@@ -1,19 +1,15 @@
|
|
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
|
5
|
-
#
|
6
|
-
# This is the model part of the submodule which provides configuration options and methods
|
7
|
-
# for locking and unlocking the user.
|
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.
|
8
6
|
module BruteForceProtection
|
9
7
|
def self.included(base)
|
10
8
|
base.sorcery_config.class_eval do
|
11
9
|
attr_accessor :failed_logins_count_attribute_name, # failed logins attribute name.
|
12
|
-
:lock_expires_at_attribute_name, # this field indicates whether user
|
13
|
-
# is banned and when it will be active again.
|
10
|
+
:lock_expires_at_attribute_name, # this field indicates whether user is banned and when it will be active again.
|
14
11
|
:consecutive_login_retries_amount_limit, # how many failed logins allowed.
|
15
|
-
:login_lock_time_period # how long the user should be banned.
|
16
|
-
# in seconds. 0 for permanent.
|
12
|
+
:login_lock_time_period # how long the user should be banned. in seconds. 0 for permanent.
|
17
13
|
end
|
18
14
|
|
19
15
|
base.sorcery_config.instance_eval do
|
@@ -34,8 +30,8 @@ module Sorcery
|
|
34
30
|
protected
|
35
31
|
|
36
32
|
def define_brute_force_protection_mongoid_fields
|
37
|
-
field sorcery_config.failed_logins_count_attribute_name,
|
38
|
-
field sorcery_config.lock_expires_at_attribute_name,
|
33
|
+
field sorcery_config.failed_logins_count_attribute_name, type: Integer
|
34
|
+
field sorcery_config.lock_expires_at_attribute_name, type: DateTime
|
39
35
|
end
|
40
36
|
end
|
41
37
|
|
@@ -5,11 +5,9 @@ module Sorcery
|
|
5
5
|
# This is the model part which handles finding the user using access tokens.
|
6
6
|
# For the controller options see Sorcery::Controller::External.
|
7
7
|
#
|
8
|
-
# Socery assumes (read: requires) you will create external users in the same table where
|
9
|
-
# you keep your regular users,
|
8
|
+
# Socery assumes (read: requires) you will create external users in the same table where you keep your regular users,
|
10
9
|
# but that you will have a separate table for keeping their external authentication data,
|
11
|
-
# and that that separate table has a few rows for each user, facebook and twitter
|
12
|
-
# for example (a one-to-many relationship).
|
10
|
+
# and that that separate table has a few rows for each user, facebook and twitter for example (a one-to-many relationship).
|
13
11
|
#
|
14
12
|
# External users will have a null crypted_password field, since we do not hold their password.
|
15
13
|
# They will not be sent activation emails on creation.
|
@@ -1,8 +1,7 @@
|
|
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
|
5
|
-
# be automatically logged in to the site on every visit,
|
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,
|
6
5
|
# until the cookie expires.
|
7
6
|
module RememberMe
|
8
7
|
def self.included(base)
|
@@ -32,8 +31,8 @@ module Sorcery
|
|
32
31
|
protected
|
33
32
|
|
34
33
|
def define_remember_me_mongoid_fields
|
35
|
-
field sorcery_config.remember_me_token_attribute_name,
|
36
|
-
field sorcery_config.remember_me_token_expires_at_attribute_name, :
|
34
|
+
field sorcery_config.remember_me_token_attribute_name, type: String
|
35
|
+
field sorcery_config.remember_me_token_expires_at_attribute_name, type: DateTime
|
37
36
|
end
|
38
37
|
|
39
38
|
end
|
@@ -5,8 +5,7 @@ module Sorcery
|
|
5
5
|
# When the user requests an email is sent to him with a url.
|
6
6
|
# The url includes a token, which is also saved with the user's record in the db.
|
7
7
|
# The token has configurable expiration.
|
8
|
-
# When the user clicks the url in the email, providing the token has not yet expired,
|
9
|
-
# he will be able to reset his password via a form.
|
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.
|
10
9
|
#
|
11
10
|
# When using this submodule, supplying a mailer is mandatory.
|
12
11
|
module ResetPassword
|
@@ -14,18 +13,11 @@ module Sorcery
|
|
14
13
|
base.sorcery_config.class_eval do
|
15
14
|
attr_accessor :reset_password_token_attribute_name, # reset password code attribute name.
|
16
15
|
:reset_password_token_expires_at_attribute_name, # expires at attribute name.
|
17
|
-
:reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering
|
18
|
-
# protection.
|
19
|
-
|
16
|
+
:reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering protection.
|
20
17
|
:reset_password_mailer, # mailer class. Needed.
|
21
|
-
:reset_password_email_method_name, # reset password email method on your
|
22
|
-
|
23
|
-
|
24
|
-
:reset_password_expiration_period, # how many seconds before the reset request
|
25
|
-
# expires. nil for never expires.
|
26
|
-
|
27
|
-
:reset_password_time_between_emails # hammering protection, how long to wait
|
28
|
-
# before allowing another email to be sent.
|
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.
|
29
21
|
|
30
22
|
end
|
31
23
|
|
@@ -69,9 +61,9 @@ module Sorcery
|
|
69
61
|
end
|
70
62
|
|
71
63
|
def define_reset_password_mongoid_fields
|
72
|
-
field sorcery_config.reset_password_token_attribute_name,
|
73
|
-
field sorcery_config.reset_password_token_expires_at_attribute_name,
|
74
|
-
field sorcery_config.reset_password_email_sent_at_attribute_name,
|
64
|
+
field sorcery_config.reset_password_token_attribute_name, type: String
|
65
|
+
field sorcery_config.reset_password_token_expires_at_attribute_name, type: DateTime
|
66
|
+
field sorcery_config.reset_password_email_sent_at_attribute_name, type: DateTime
|
75
67
|
end
|
76
68
|
end
|
77
69
|
|
@@ -8,27 +8,14 @@ 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, # the attribute name to hold activation state
|
12
|
-
|
13
|
-
|
14
|
-
:
|
15
|
-
# (sent by email).
|
16
|
-
|
17
|
-
:activation_token_expires_at_attribute_name, # the attribute name to hold activation code
|
18
|
-
# expiration date.
|
19
|
-
|
20
|
-
:activation_token_expiration_period, # how many seconds before the activation code
|
21
|
-
# expires. nil for never expires.
|
22
|
-
|
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.
|
23
15
|
:user_activation_mailer, # your mailer class. Required.
|
24
|
-
:activation_needed_email_method_name, # activation needed email method on your
|
25
|
-
|
26
|
-
|
27
|
-
:activation_success_email_method_name, # activation success email method on your
|
28
|
-
# mailer class.
|
29
|
-
|
30
|
-
:prevent_non_active_users_to_login # do you want to prevent or allow users that
|
31
|
-
# did not activate by email to login?
|
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?
|
32
19
|
end
|
33
20
|
|
34
21
|
base.sorcery_config.instance_eval do
|
@@ -80,9 +67,9 @@ module Sorcery
|
|
80
67
|
|
81
68
|
def define_user_activation_mongoid_fields
|
82
69
|
self.class_eval do
|
83
|
-
field sorcery_config.activation_state_attribute_name,
|
84
|
-
field sorcery_config.activation_token_attribute_name,
|
85
|
-
field sorcery_config.activation_token_expires_at_attribute_name, :
|
70
|
+
field sorcery_config.activation_state_attribute_name, type: String
|
71
|
+
field sorcery_config.activation_token_attribute_name, type: String
|
72
|
+
field sorcery_config.activation_token_expires_at_attribute_name, type: DateTime
|
86
73
|
end
|
87
74
|
end
|
88
75
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module Model
|
3
3
|
# This module encapsulates the logic for temporary token.
|
4
|
-
# A temporary token is created to identify a user in scenarios
|
5
|
-
# such as reseting password and activating the user by email.
|
4
|
+
# A temporary token is created to identify a user in scenarios such as reseting password and activating the user by email.
|
6
5
|
module TemporaryToken
|
7
6
|
def self.included(base)
|
8
7
|
base.extend(ClassMethods)
|
@@ -11,7 +10,7 @@ module Sorcery
|
|
11
10
|
module ClassMethods
|
12
11
|
def load_from_token(token, token_attr_name, token_expiration_date_attr)
|
13
12
|
return nil if token.blank?
|
14
|
-
user =
|
13
|
+
user = find_by_token(token_attr_name,token)
|
15
14
|
if !user.blank? && !user.send(token_expiration_date_attr).nil?
|
16
15
|
return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
|
17
16
|
end
|
@@ -15,8 +15,7 @@ module Sorcery
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# a patch to fix a bug in testing that happens when you 'destroy' a session twice.
|
18
|
-
# After the first destroy, the session is an ordinary hash, and then when destroy
|
19
|
-
# is called again there's an exception.
|
18
|
+
# After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
|
20
19
|
class ::Hash
|
21
20
|
def destroy
|
22
21
|
clear
|
@@ -4,11 +4,7 @@ module Sorcery
|
|
4
4
|
module Rails
|
5
5
|
include ::Sorcery::TestHelpers::Rails
|
6
6
|
|
7
|
-
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [
|
8
|
-
:register_last_activity_time_to_db,
|
9
|
-
:deny_banned_user,
|
10
|
-
:validate_session
|
11
|
-
]
|
7
|
+
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
|
12
8
|
|
13
9
|
def sorcery_reload!(submodules = [], options = {})
|
14
10
|
reload_user_class
|
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.5.
|
8
|
+
s.version = "0.5.21"
|
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-05-20}
|
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 = [
|
@@ -218,13 +218,6 @@ Gem::Specification.new do |s|
|
|
218
218
|
"spec/rails3_mongoid/spec/user_reset_password_spec.rb",
|
219
219
|
"spec/rails3_mongoid/spec/user_spec.rb",
|
220
220
|
"spec/rails3_mongoid/vendor/plugins/.gitkeep",
|
221
|
-
"spec/shared_examples/user_activation_shared_examples.rb",
|
222
|
-
"spec/shared_examples/user_activity_logging_shared_examples.rb",
|
223
|
-
"spec/shared_examples/user_brute_force_protection_shared_examples.rb",
|
224
|
-
"spec/shared_examples/user_oauth_shared_examples.rb",
|
225
|
-
"spec/shared_examples/user_remember_me_shared_examples.rb",
|
226
|
-
"spec/shared_examples/user_reset_password_shared_examples.rb",
|
227
|
-
"spec/shared_examples/user_shared_examples.rb",
|
228
221
|
"spec/sinatra/Gemfile",
|
229
222
|
"spec/sinatra/Gemfile.lock",
|
230
223
|
"spec/sinatra/Rakefile",
|
@@ -362,13 +355,6 @@ Gem::Specification.new do |s|
|
|
362
355
|
"spec/rails3_mongoid/spec/user_remember_me_spec.rb",
|
363
356
|
"spec/rails3_mongoid/spec/user_reset_password_spec.rb",
|
364
357
|
"spec/rails3_mongoid/spec/user_spec.rb",
|
365
|
-
"spec/shared_examples/user_activation_shared_examples.rb",
|
366
|
-
"spec/shared_examples/user_activity_logging_shared_examples.rb",
|
367
|
-
"spec/shared_examples/user_brute_force_protection_shared_examples.rb",
|
368
|
-
"spec/shared_examples/user_oauth_shared_examples.rb",
|
369
|
-
"spec/shared_examples/user_remember_me_shared_examples.rb",
|
370
|
-
"spec/shared_examples/user_reset_password_shared_examples.rb",
|
371
|
-
"spec/shared_examples/user_shared_examples.rb",
|
372
358
|
"spec/sinatra/authentication.rb",
|
373
359
|
"spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb",
|
374
360
|
"spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb",
|
data/spec/Gemfile.lock
CHANGED
data/spec/rails3/Gemfile.lock
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../app/mailers/sorcery_mailer')
|
3
|
-
require File.expand_path(File.dirname(__FILE__) + '/../../shared_examples/user_activation_shared_examples')
|
4
3
|
|
5
4
|
describe "User with activation submodule" do
|
6
5
|
before(:all) do
|
@@ -11,6 +10,173 @@ describe "User with activation submodule" do
|
|
11
10
|
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
12
11
|
end
|
13
12
|
|
14
|
-
|
13
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
14
|
+
describe User, "loaded plugin configuration" do
|
15
|
+
before(:all) do
|
16
|
+
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
User.sorcery_config.reset!
|
21
|
+
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should enable configuration option 'activation_state_attribute_name'" do
|
25
|
+
sorcery_model_property_set(:activation_state_attribute_name, :status)
|
26
|
+
User.sorcery_config.activation_state_attribute_name.should equal(:status)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should enable configuration option 'activation_token_attribute_name'" do
|
30
|
+
sorcery_model_property_set(:activation_token_attribute_name, :code)
|
31
|
+
User.sorcery_config.activation_token_attribute_name.should equal(:code)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should enable configuration option 'user_activation_mailer'" do
|
35
|
+
sorcery_model_property_set(:user_activation_mailer, TestMailer)
|
36
|
+
User.sorcery_config.user_activation_mailer.should equal(TestMailer)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should enable configuration option 'activation_needed_email_method_name'" do
|
40
|
+
sorcery_model_property_set(:activation_needed_email_method_name, :my_activation_email)
|
41
|
+
User.sorcery_config.activation_needed_email_method_name.should equal(:my_activation_email)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should enable configuration option 'activation_success_email_method_name'" do
|
45
|
+
sorcery_model_property_set(:activation_success_email_method_name, :my_activation_email)
|
46
|
+
User.sorcery_config.activation_success_email_method_name.should equal(:my_activation_email)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "if mailer is nil on activation, throw exception!" do
|
50
|
+
expect{sorcery_reload!([:user_activation])}.to raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# ----------------- ACTIVATION PROCESS -----------------------
|
55
|
+
describe User, "activation process" do
|
56
|
+
before(:all) do
|
57
|
+
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
58
|
+
end
|
59
|
+
|
60
|
+
before(:each) do
|
61
|
+
create_new_user
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should initialize user state to 'pending'" do
|
65
|
+
@user.activation_state.should == "pending"
|
66
|
+
end
|
67
|
+
|
68
|
+
specify { @user.should respond_to(:activate!) }
|
69
|
+
|
70
|
+
it "should clear activation code and change state to 'active' on activation" do
|
71
|
+
activation_token = @user.activation_token
|
72
|
+
@user.activate!
|
73
|
+
@user2 = User.find(@user.id) # go to db to make sure it was saved and not just in memory
|
74
|
+
@user2.activation_token.should be_nil
|
75
|
+
@user2.activation_state.should == "active"
|
76
|
+
User.find_by_activation_token(activation_token).should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should send the user an activation email" do
|
80
|
+
old_size = ActionMailer::Base.deliveries.size
|
81
|
+
create_new_user
|
82
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
83
|
+
end
|
84
|
+
|
85
|
+
it "subsequent saves do not send activation email" do
|
86
|
+
old_size = ActionMailer::Base.deliveries.size
|
87
|
+
@user.username = "Shauli"
|
88
|
+
@user.save!
|
89
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should send the user an activation success email on successful activation" do
|
93
|
+
old_size = ActionMailer::Base.deliveries.size
|
94
|
+
@user.activate!
|
95
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
96
|
+
end
|
97
|
+
|
98
|
+
it "subsequent saves do not send activation success email" do
|
99
|
+
@user.activate!
|
100
|
+
old_size = ActionMailer::Base.deliveries.size
|
101
|
+
@user.username = "Shauli"
|
102
|
+
@user.save!
|
103
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
104
|
+
end
|
105
|
+
|
106
|
+
it "activation needed email is optional" do
|
107
|
+
sorcery_model_property_set(:activation_needed_email_method_name, nil)
|
108
|
+
old_size = ActionMailer::Base.deliveries.size
|
109
|
+
create_new_user
|
110
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
111
|
+
end
|
112
|
+
|
113
|
+
it "activation success email is optional" do
|
114
|
+
sorcery_model_property_set(:activation_success_email_method_name, nil)
|
115
|
+
old_size = ActionMailer::Base.deliveries.size
|
116
|
+
@user.activate!
|
117
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe User, "prevent non-active login feature" do
|
122
|
+
before(:all) do
|
123
|
+
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not allow a non-active user to authenticate" do
|
127
|
+
create_new_user
|
128
|
+
User.authenticate(@user.username,'secret').should be_false
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should allow a non-active user to authenticate if configured so" do
|
132
|
+
create_new_user
|
133
|
+
sorcery_model_property_set(:prevent_non_active_users_to_login, false)
|
134
|
+
User.authenticate(@user.username,'secret').should be_true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe User, "load_from_activation_token" do
|
139
|
+
before(:all) do
|
140
|
+
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
141
|
+
end
|
142
|
+
|
143
|
+
after(:each) do
|
144
|
+
Timecop.return
|
145
|
+
end
|
146
|
+
|
147
|
+
it "load_from_activation_token should return user when token is found" do
|
148
|
+
create_new_user
|
149
|
+
User.load_from_activation_token(@user.activation_token).should == @user
|
150
|
+
end
|
151
|
+
|
152
|
+
it "load_from_activation_token should NOT return user when token is NOT found" do
|
153
|
+
create_new_user
|
154
|
+
User.load_from_activation_token("a").should == nil
|
155
|
+
end
|
156
|
+
|
157
|
+
it "load_from_activation_token should return user when token is found and not expired" do
|
158
|
+
sorcery_model_property_set(:activation_token_expiration_period, 500)
|
159
|
+
create_new_user
|
160
|
+
User.load_from_activation_token(@user.activation_token).should == @user
|
161
|
+
end
|
162
|
+
|
163
|
+
it "load_from_activation_token should NOT return user when token is found and expired" do
|
164
|
+
sorcery_model_property_set(:activation_token_expiration_period, 0.1)
|
165
|
+
create_new_user
|
166
|
+
Timecop.travel(Time.now+0.5)
|
167
|
+
User.load_from_activation_token(@user.activation_token).should == nil
|
168
|
+
end
|
169
|
+
|
170
|
+
it "load_from_activation_token should return nil if token is blank" do
|
171
|
+
User.load_from_activation_token(nil).should == nil
|
172
|
+
User.load_from_activation_token("").should == nil
|
173
|
+
end
|
174
|
+
|
175
|
+
it "load_from_activation_token should always be valid if expiration period is nil" do
|
176
|
+
sorcery_model_property_set(:activation_token_expiration_period, nil)
|
177
|
+
create_new_user
|
178
|
+
User.load_from_activation_token(@user.activation_token).should == @user
|
179
|
+
end
|
180
|
+
end
|
15
181
|
|
16
182
|
end
|