sorcery 0.5.21 → 0.5.30
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 +5 -3
- data/lib/sorcery/controller/submodules/activity_logging.rb +10 -6
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -3
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +10 -5
- data/lib/sorcery/controller/submodules/remember_me.rb +13 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +3 -1
- data/lib/sorcery/crypto_providers/aes256.rb +8 -5
- data/lib/sorcery/crypto_providers/bcrypt.rb +12 -6
- data/lib/sorcery/crypto_providers/sha256.rb +2 -1
- data/lib/sorcery/crypto_providers/sha512.rb +2 -1
- data/lib/sorcery/initializers/initializer.rb +125 -36
- data/lib/sorcery/model.rb +28 -15
- 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 +7 -6
- data/lib/sorcery/model/submodules/brute_force_protection.rb +10 -6
- data/lib/sorcery/model/submodules/external.rb +4 -2
- data/lib/sorcery/model/submodules/remember_me.rb +4 -3
- data/lib/sorcery/model/submodules/reset_password.rb +16 -8
- data/lib/sorcery/model/submodules/user_activation.rb +23 -10
- data/lib/sorcery/model/temporary_token.rb +3 -2
- data/lib/sorcery/test_helpers/internal.rb +2 -1
- data/lib/sorcery/test_helpers/internal/rails.rb +5 -1
- data/sorcery.gemspec +16 -2
- data/spec/Gemfile.lock +1 -1
- data/spec/rails3/Gemfile.lock +1 -1
- data/spec/rails3/spec/user_activation_spec.rb +2 -168
- data/spec/rails3/spec/user_activity_logging_spec.rb +2 -30
- data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -35
- data/spec/rails3/spec/user_oauth_spec.rb +2 -26
- data/spec/rails3/spec/user_remember_me_spec.rb +2 -45
- data/spec/rails3/spec/user_reset_password_spec.rb +3 -168
- data/spec/rails3/spec/user_spec.rb +3 -283
- 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 +2 -171
- data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +2 -25
- data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +2 -35
- data/spec/rails3_mongoid/spec/user_oauth_spec.rb +2 -28
- data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +2 -45
- data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +2 -176
- data/spec/rails3_mongoid/spec/user_spec.rb +3 -285
- data/spec/shared_examples/user_activation_shared_examples.rb +173 -0
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +27 -0
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +37 -0
- data/spec/shared_examples/user_oauth_shared_examples.rb +30 -0
- data/spec/shared_examples/user_remember_me_shared_examples.rb +47 -0
- data/spec/shared_examples/user_reset_password_shared_examples.rb +177 -0
- data/spec/shared_examples/user_shared_examples.rb +292 -0
- data/spec/sinatra/Gemfile.lock +1 -1
- data/spec/sinatra_modular/Gemfile.lock +1 -1
- metadata +16 -2
data/lib/sorcery/model.rb
CHANGED
@@ -3,7 +3,8 @@ 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
|
6
|
+
# When included it defines a single method: 'activate_sorcery!' which when called adds the other capabilities
|
7
|
+
# to the class.
|
7
8
|
# This method is also the place to configure the plugin in the Model layer.
|
8
9
|
module Model
|
9
10
|
def self.included(klass)
|
@@ -20,7 +21,8 @@ module Sorcery
|
|
20
21
|
begin
|
21
22
|
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
22
23
|
rescue NameError
|
23
|
-
# don't stop on a missing submodule. Needed because some submodules are only defined
|
24
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined
|
25
|
+
# in the controller side.
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -30,11 +32,10 @@ module Sorcery
|
|
30
32
|
|
31
33
|
# Mongoid support
|
32
34
|
self.class_eval do
|
33
|
-
field sorcery_config.username_attribute_name,
|
34
|
-
|
35
|
-
field sorcery_config.
|
36
|
-
field sorcery_config.
|
37
|
-
field sorcery_config.salt_attribute_name, type: String
|
35
|
+
field sorcery_config.username_attribute_name, :type => String
|
36
|
+
field sorcery_config.email_attribute_name, :type => String unless sorcery_config.username_attribute_name == sorcery_config.email_attribute_name
|
37
|
+
field sorcery_config.crypted_password_attribute_name, :type => String
|
38
|
+
field sorcery_config.salt_attribute_name, :type => String
|
38
39
|
end if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
|
39
40
|
|
40
41
|
# add virtual password accessor and ORM callbacks
|
@@ -147,26 +148,38 @@ module Sorcery
|
|
147
148
|
end
|
148
149
|
|
149
150
|
# Each class which calls 'activate_sorcery!' receives an instance of this class.
|
150
|
-
# Every submodule which gets loaded may add accessors to this class so that all
|
151
|
+
# Every submodule which gets loaded may add accessors to this class so that all
|
152
|
+
# options will be configured from a single place.
|
151
153
|
class Config
|
152
154
|
|
153
|
-
attr_accessor :username_attribute_name, # change default username attribute, for example, to use :email
|
154
|
-
|
155
|
+
attr_accessor :username_attribute_name, # change default username attribute, for example, to use :email
|
156
|
+
# as the login.
|
157
|
+
|
158
|
+
:password_attribute_name, # change *virtual* password attribute, the one which is used
|
159
|
+
# until an encrypted one is generated.
|
160
|
+
|
155
161
|
:email_attribute_name, # change default email attribute.
|
156
162
|
:crypted_password_attribute_name, # change default crypted_password attribute.
|
157
163
|
:salt_join_token, # what pattern to use to join the password with the salt
|
158
164
|
:salt_attribute_name, # change default salt attribute.
|
159
165
|
:stretches, # how many times to apply encryption to the password.
|
160
|
-
:encryption_key, # encryption key used to encrypt reversible encryptions such as
|
161
|
-
|
166
|
+
:encryption_key, # encryption key used to encrypt reversible encryptions such as
|
167
|
+
# AES256.
|
168
|
+
|
169
|
+
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for
|
170
|
+
# ActiveRecord's STI.
|
162
171
|
|
163
172
|
:submodules, # configured in config/application.rb
|
164
|
-
:before_authenticate, # an array of method names to call before authentication
|
165
|
-
|
173
|
+
:before_authenticate, # an array of method names to call before authentication
|
174
|
+
# completes. used internally.
|
175
|
+
|
176
|
+
:after_config # an array of method names to call after configuration by user.
|
177
|
+
# used internally.
|
166
178
|
|
167
179
|
attr_reader :encryption_provider, # change default encryption_provider.
|
168
180
|
:custom_encryption_provider, # use an external encryption class.
|
169
|
-
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
|
181
|
+
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
|
182
|
+
# for available options.
|
170
183
|
|
171
184
|
def initialize
|
172
185
|
@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_sorcery_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_sorcery_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
|
7
|
+
# for a while.
|
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,7 +14,8 @@ 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
|
17
|
+
:activity_timeout # how long since last activity is
|
18
|
+
#the user defined logged out?
|
18
19
|
end
|
19
20
|
|
20
21
|
base.sorcery_config.instance_eval do
|
@@ -38,9 +39,9 @@ module Sorcery
|
|
38
39
|
protected
|
39
40
|
|
40
41
|
def define_activity_logging_mongoid_fields
|
41
|
-
field sorcery_config.last_login_at_attribute_name,
|
42
|
-
field sorcery_config.last_logout_at_attribute_name,
|
43
|
-
field sorcery_config.last_activity_at_attribute_name, type
|
42
|
+
field sorcery_config.last_login_at_attribute_name, :type => DateTime
|
43
|
+
field sorcery_config.last_logout_at_attribute_name, :type => DateTime
|
44
|
+
field sorcery_config.last_activity_at_attribute_name, :type => DateTime
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
@@ -1,15 +1,19 @@
|
|
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
|
-
#
|
4
|
+
# This module helps protect user accounts by locking them down after too many failed attemps
|
5
|
+
# to login were detected.
|
6
|
+
# This is the model part of the submodule which provides configuration options and methods
|
7
|
+
# for locking and unlocking the user.
|
6
8
|
module BruteForceProtection
|
7
9
|
def self.included(base)
|
8
10
|
base.sorcery_config.class_eval do
|
9
11
|
attr_accessor :failed_logins_count_attribute_name, # failed logins attribute name.
|
10
|
-
:lock_expires_at_attribute_name, # this field indicates whether user
|
12
|
+
:lock_expires_at_attribute_name, # this field indicates whether user
|
13
|
+
# is banned and when it will be active again.
|
11
14
|
:consecutive_login_retries_amount_limit, # how many failed logins allowed.
|
12
|
-
:login_lock_time_period # how long the user should be banned.
|
15
|
+
:login_lock_time_period # how long the user should be banned.
|
16
|
+
# in seconds. 0 for permanent.
|
13
17
|
end
|
14
18
|
|
15
19
|
base.sorcery_config.instance_eval do
|
@@ -30,8 +34,8 @@ module Sorcery
|
|
30
34
|
protected
|
31
35
|
|
32
36
|
def define_brute_force_protection_mongoid_fields
|
33
|
-
field sorcery_config.failed_logins_count_attribute_name,
|
34
|
-
field sorcery_config.lock_expires_at_attribute_name,
|
37
|
+
field sorcery_config.failed_logins_count_attribute_name, :type => Integer
|
38
|
+
field sorcery_config.lock_expires_at_attribute_name, :type => DateTime
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
@@ -5,9 +5,11 @@ 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
|
8
|
+
# Socery assumes (read: requires) you will create external users in the same table where
|
9
|
+
# you keep your regular users,
|
9
10
|
# 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
|
11
|
+
# and that that separate table has a few rows for each user, facebook and twitter
|
12
|
+
# for example (a one-to-many relationship).
|
11
13
|
#
|
12
14
|
# External users will have a null crypted_password field, since we do not hold their password.
|
13
15
|
# They will not be sent activation emails on creation.
|
@@ -1,7 +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
|
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,
|
5
6
|
# until the cookie expires.
|
6
7
|
module RememberMe
|
7
8
|
def self.included(base)
|
@@ -31,8 +32,8 @@ module Sorcery
|
|
31
32
|
protected
|
32
33
|
|
33
34
|
def define_remember_me_mongoid_fields
|
34
|
-
field sorcery_config.remember_me_token_attribute_name,
|
35
|
-
field sorcery_config.remember_me_token_expires_at_attribute_name, type
|
35
|
+
field sorcery_config.remember_me_token_attribute_name, :type => String
|
36
|
+
field sorcery_config.remember_me_token_expires_at_attribute_name, :type => Time
|
36
37
|
end
|
37
38
|
|
38
39
|
end
|
@@ -5,7 +5,8 @@ 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,
|
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.
|
9
10
|
#
|
10
11
|
# When using this submodule, supplying a mailer is mandatory.
|
11
12
|
module ResetPassword
|
@@ -13,11 +14,18 @@ module Sorcery
|
|
13
14
|
base.sorcery_config.class_eval do
|
14
15
|
attr_accessor :reset_password_token_attribute_name, # reset password code attribute name.
|
15
16
|
: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
|
17
|
+
:reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering
|
18
|
+
# protection.
|
19
|
+
|
17
20
|
:reset_password_mailer, # mailer class. Needed.
|
18
|
-
:reset_password_email_method_name, # reset password email method on your
|
19
|
-
|
20
|
-
|
21
|
+
:reset_password_email_method_name, # reset password email method on your
|
22
|
+
# mailer class.
|
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.
|
21
29
|
|
22
30
|
end
|
23
31
|
|
@@ -61,9 +69,9 @@ module Sorcery
|
|
61
69
|
end
|
62
70
|
|
63
71
|
def define_reset_password_mongoid_fields
|
64
|
-
field sorcery_config.reset_password_token_attribute_name,
|
65
|
-
field sorcery_config.reset_password_token_expires_at_attribute_name,
|
66
|
-
field sorcery_config.reset_password_email_sent_at_attribute_name,
|
72
|
+
field sorcery_config.reset_password_token_attribute_name, :type => String
|
73
|
+
field sorcery_config.reset_password_token_expires_at_attribute_name, :type => DateTime
|
74
|
+
field sorcery_config.reset_password_email_sent_at_attribute_name, :type => DateTime
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
@@ -8,14 +8,27 @@ 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
|
-
:
|
11
|
+
attr_accessor :activation_state_attribute_name, # the attribute name to hold activation state
|
12
|
+
# (active/pending).
|
13
|
+
|
14
|
+
:activation_token_attribute_name, # the attribute name to hold activation code
|
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
|
+
|
15
23
|
:user_activation_mailer, # your mailer class. Required.
|
16
|
-
:activation_needed_email_method_name, # activation needed email method on your
|
17
|
-
|
18
|
-
|
24
|
+
:activation_needed_email_method_name, # activation needed email method on your
|
25
|
+
# mailer class.
|
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?
|
19
32
|
end
|
20
33
|
|
21
34
|
base.sorcery_config.instance_eval do
|
@@ -67,9 +80,9 @@ module Sorcery
|
|
67
80
|
|
68
81
|
def define_user_activation_mongoid_fields
|
69
82
|
self.class_eval do
|
70
|
-
field sorcery_config.activation_state_attribute_name,
|
71
|
-
field sorcery_config.activation_token_attribute_name,
|
72
|
-
field sorcery_config.activation_token_expires_at_attribute_name, type
|
83
|
+
field sorcery_config.activation_state_attribute_name, :type => String
|
84
|
+
field sorcery_config.activation_token_attribute_name, :type => String
|
85
|
+
field sorcery_config.activation_token_expires_at_attribute_name, :type => DateTime
|
73
86
|
end
|
74
87
|
end
|
75
88
|
end
|
@@ -1,7 +1,8 @@
|
|
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
|
4
|
+
# A temporary token is created to identify a user in scenarios
|
5
|
+
# such as reseting password and activating the user by email.
|
5
6
|
module TemporaryToken
|
6
7
|
def self.included(base)
|
7
8
|
base.extend(ClassMethods)
|
@@ -10,7 +11,7 @@ module Sorcery
|
|
10
11
|
module ClassMethods
|
11
12
|
def load_from_token(token, token_attr_name, token_expiration_date_attr)
|
12
13
|
return nil if token.blank?
|
13
|
-
user =
|
14
|
+
user = find_by_sorcery_token(token_attr_name,token)
|
14
15
|
if !user.blank? && !user.send(token_expiration_date_attr).nil?
|
15
16
|
return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
|
16
17
|
end
|
@@ -15,7 +15,8 @@ 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
|
18
|
+
# After the first destroy, the session is an ordinary hash, and then when destroy
|
19
|
+
# is called again there's an exception.
|
19
20
|
class ::Hash
|
20
21
|
def destroy
|
21
22
|
clear
|
@@ -4,7 +4,11 @@ module Sorcery
|
|
4
4
|
module Rails
|
5
5
|
include ::Sorcery::TestHelpers::Rails
|
6
6
|
|
7
|
-
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [
|
7
|
+
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [
|
8
|
+
:register_last_activity_time_to_db,
|
9
|
+
:deny_banned_user,
|
10
|
+
:validate_session
|
11
|
+
]
|
8
12
|
|
9
13
|
def sorcery_reload!(submodules = [], options = {})
|
10
14
|
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.30"
|
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-07-01}
|
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,6 +218,13 @@ 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",
|
221
228
|
"spec/sinatra/Gemfile",
|
222
229
|
"spec/sinatra/Gemfile.lock",
|
223
230
|
"spec/sinatra/Rakefile",
|
@@ -355,6 +362,13 @@ Gem::Specification.new do |s|
|
|
355
362
|
"spec/rails3_mongoid/spec/user_remember_me_spec.rb",
|
356
363
|
"spec/rails3_mongoid/spec/user_reset_password_spec.rb",
|
357
364
|
"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",
|
358
372
|
"spec/sinatra/authentication.rb",
|
359
373
|
"spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb",
|
360
374
|
"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,5 +1,6 @@
|
|
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')
|
3
4
|
|
4
5
|
describe "User with activation submodule" do
|
5
6
|
before(:all) do
|
@@ -10,173 +11,6 @@ describe "User with activation submodule" do
|
|
10
11
|
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
11
12
|
end
|
12
13
|
|
13
|
-
|
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
|
14
|
+
it_behaves_like "rails_3_activation_model"
|
181
15
|
|
182
16
|
end
|