sorcery 0.8.6 → 0.9.1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +75 -14
- data/CHANGELOG.md +32 -1
- data/Gemfile +1 -0
- data/README.md +138 -86
- data/gemfiles/active_record-rails40.gemfile +7 -0
- data/gemfiles/active_record-rails41.gemfile +3 -2
- data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
- data/gemfiles/mongo_mapper-rails41.gemfile +2 -1
- data/gemfiles/mongoid-rails40.gemfile +9 -0
- data/gemfiles/mongoid-rails41.gemfile +3 -5
- data/gemfiles/mongoid3-rails32.gemfile +9 -0
- data/lib/generators/sorcery/USAGE +1 -1
- data/lib/generators/sorcery/install_generator.rb +19 -5
- data/lib/generators/sorcery/templates/initializer.rb +36 -10
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +3 -1
- data/lib/generators/sorcery/templates/migration/core.rb +2 -2
- data/lib/generators/sorcery/templates/migration/external.rb +3 -1
- data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
- data/lib/sorcery/adapters/base_adapter.rb +30 -0
- data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
- data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
- data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
- data/lib/sorcery/controller/config.rb +65 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
- data/lib/sorcery/controller/submodules/external.rb +9 -29
- data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
- data/lib/sorcery/controller.rb +5 -64
- data/lib/sorcery/model/config.rb +96 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +29 -36
- data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -37
- data/lib/sorcery/model/submodules/external.rb +53 -9
- data/lib/sorcery/model/submodules/remember_me.rb +12 -31
- data/lib/sorcery/model/submodules/reset_password.rb +21 -39
- data/lib/sorcery/model/submodules/user_activation.rb +21 -63
- data/lib/sorcery/model/temporary_token.rb +4 -4
- data/lib/sorcery/model.rb +47 -175
- data/lib/sorcery/providers/base.rb +11 -0
- data/lib/sorcery/providers/facebook.rb +16 -5
- data/lib/sorcery/providers/github.rb +11 -2
- data/lib/sorcery/providers/google.rb +1 -1
- data/lib/sorcery/providers/heroku.rb +57 -0
- data/lib/sorcery/providers/jira.rb +77 -0
- data/lib/sorcery/providers/linkedin.rb +1 -1
- data/lib/sorcery/providers/liveid.rb +1 -1
- data/lib/sorcery/providers/salesforce.rb +50 -0
- data/lib/sorcery/providers/twitter.rb +1 -1
- data/lib/sorcery/providers/vk.rb +6 -4
- data/lib/sorcery/providers/xing.rb +2 -2
- data/lib/sorcery/test_helpers/internal.rb +7 -3
- data/lib/sorcery/test_helpers/rails/controller.rb +5 -1
- data/lib/sorcery/version.rb +3 -0
- data/lib/sorcery.rb +75 -43
- data/sorcery.gemspec +6 -2
- data/spec/active_record/user_activity_logging_spec.rb +9 -0
- data/spec/controllers/controller_activity_logging_spec.rb +124 -0
- data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
- data/spec/{active_record → controllers}/controller_http_basic_auth_spec.rb +14 -11
- data/spec/{active_record → controllers}/controller_oauth2_spec.rb +151 -64
- data/spec/{active_record → controllers}/controller_oauth_spec.rb +94 -70
- data/spec/{active_record → controllers}/controller_remember_me_spec.rb +32 -12
- data/spec/{active_record → controllers}/controller_session_timeout_spec.rb +15 -5
- data/spec/{shared_examples/controller_shared_examples.rb → controllers/controller_spec.rb} +34 -19
- data/spec/{datamapper → data_mapper}/user_activation_spec.rb +1 -1
- data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
- data/spec/{datamapper → data_mapper}/user_brute_force_protection_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_oauth_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_remember_me_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_reset_password_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_spec.rb +1 -1
- data/spec/mongoid/user_spec.rb +13 -0
- data/spec/orm/active_record.rb +12 -0
- data/spec/orm/{datamapper.rb → data_mapper.rb} +16 -2
- data/spec/orm/mongo_mapper.rb +0 -1
- data/spec/orm/mongoid.rb +4 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +62 -1
- data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
- data/spec/rails_app/config/routes.rb +9 -0
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
- data/spec/shared_examples/user_activation_shared_examples.rb +7 -7
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +73 -5
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +127 -9
- data/spec/shared_examples/user_oauth_shared_examples.rb +3 -6
- data/spec/shared_examples/user_remember_me_shared_examples.rb +6 -3
- data/spec/shared_examples/user_reset_password_shared_examples.rb +10 -10
- data/spec/shared_examples/user_shared_examples.rb +146 -46
- data/spec/spec_helper.rb +7 -22
- metadata +36 -57
- data/Gemfile.rails4 +0 -22
- data/VERSION +0 -1
- data/lib/sorcery/model/adapters/active_record.rb +0 -54
- data/lib/sorcery/model/adapters/datamapper.rb +0 -123
- data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -60
- data/lib/sorcery/model/adapters/mongoid.rb +0 -88
- data/lib/sorcery/test_helpers/rails.rb +0 -7
- data/spec/active_record/controller_activity_logging_spec.rb +0 -29
- data/spec/active_record/controller_brute_force_protection_spec.rb +0 -158
- data/spec/active_record/controller_spec.rb +0 -8
- data/spec/active_record/integration_spec.rb +0 -23
- data/spec/datamapper/controller_activity_logging_spec.rb +0 -17
- data/spec/datamapper/controller_spec.rb +0 -8
- data/spec/datamapper/user_activity_logging_spec.rb +0 -9
- data/spec/mongo_mapper/controller_spec.rb +0 -8
- data/spec/mongoid/controller_activity_logging_spec.rb +0 -16
- data/spec/mongoid/controller_spec.rb +0 -8
- data/spec/rails_app/public/404.html +0 -26
- data/spec/rails_app/public/422.html +0 -26
- data/spec/rails_app/public/500.html +0 -26
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/javascripts/application.js +0 -2
- data/spec/rails_app/public/javascripts/controls.js +0 -965
- data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
- data/spec/rails_app/public/javascripts/effects.js +0 -1123
- data/spec/rails_app/public/javascripts/prototype.js +0 -6001
- data/spec/rails_app/public/javascripts/rails.js +0 -175
- data/spec/rails_app/public/robots.txt +0 -5
- data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
- data/spec/shared_examples/controller_activity_logging_shared_examples.rb +0 -125
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -52
- data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -62
- /data/spec/rails_app/app/{datamapper → data_mapper}/authentication.rb +0 -0
- /data/spec/rails_app/app/{datamapper → data_mapper}/user.rb +0 -0
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
module Sorcery
|
|
2
|
-
module Model
|
|
3
|
-
module Adapters
|
|
4
|
-
module DataMapper
|
|
5
|
-
def self.included(klass)
|
|
6
|
-
klass.extend ClassMethods
|
|
7
|
-
klass.send(:include, InstanceMethods)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module InstanceMethods
|
|
11
|
-
def increment(attr)
|
|
12
|
-
self[attr] ||= 0
|
|
13
|
-
self[attr] += 1
|
|
14
|
-
self
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def update_many_attributes(attrs)
|
|
18
|
-
attrs.each do |name, value|
|
|
19
|
-
value = value.utc if value.is_a?(ActiveSupport::TimeWithZone)
|
|
20
|
-
self.send(:"#{name}=", value)
|
|
21
|
-
end
|
|
22
|
-
self.class.get(self.id).update(attrs)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def update_single_attribute(name, value)
|
|
26
|
-
update_many_attributes(name => value)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def sorcery_save(options = {})
|
|
30
|
-
if options.key?(:validate) && ! options[:validate]
|
|
31
|
-
save!
|
|
32
|
-
else
|
|
33
|
-
save
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
module ClassMethods
|
|
39
|
-
def find(id)
|
|
40
|
-
get(id)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def delete_all
|
|
44
|
-
destroy
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# NOTE
|
|
48
|
-
# DM Adapter dependent
|
|
49
|
-
# DM creates MySQL tables case insensitive by default
|
|
50
|
-
# http://datamapper.lighthouseapp.com/projects/20609-datamapper/tickets/1105
|
|
51
|
-
def find_by_credentials(credentials)
|
|
52
|
-
credential = credentials[0].dup
|
|
53
|
-
credential.downcase! if @sorcery_config.downcase_username_before_authenticating
|
|
54
|
-
@sorcery_config.username_attribute_names.each do |name|
|
|
55
|
-
@user = first(name => credential)
|
|
56
|
-
break if @user
|
|
57
|
-
end
|
|
58
|
-
!!@user ? get(@user.id) : nil
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def find_by_provider_and_uid(provider, uid)
|
|
62
|
-
@user_klass ||= ::Sorcery::Controller::Config.user_class.to_s.constantize
|
|
63
|
-
user = first(@user_klass.sorcery_config.provider_attribute_name => provider, @user_klass.sorcery_config.provider_uid_attribute_name => uid)
|
|
64
|
-
!!user ? get(user.id) : nil
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def find_by_id(id)
|
|
68
|
-
find(id)
|
|
69
|
-
rescue ::DataMapper::ObjectNotFoundError
|
|
70
|
-
nil
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def find_by_activation_token(token)
|
|
74
|
-
user = first(sorcery_config.activation_token_attribute_name => token)
|
|
75
|
-
!!user ? get(user.id) : nil
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def find_by_remember_me_token(token)
|
|
79
|
-
user = first(sorcery_config.remember_me_token_attribute_name => token)
|
|
80
|
-
!!user ? get(user.id) : nil
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def find_by_username(username)
|
|
84
|
-
user = nil
|
|
85
|
-
sorcery_config.username_attribute_names.each do |name|
|
|
86
|
-
user = first(name => username)
|
|
87
|
-
break if user
|
|
88
|
-
end
|
|
89
|
-
!!user ? get(user.id) : nil
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def transaction(&blk)
|
|
93
|
-
tap(&blk)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def find_by_sorcery_token(token_attr_name, token)
|
|
97
|
-
user = first(token_attr_name => token)
|
|
98
|
-
!!user ? get(user.id) : nil
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def find_by_email(email)
|
|
102
|
-
user = first(sorcery_config.email_attribute_name => email)
|
|
103
|
-
!!user ? get(user.id) : nil
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# NOTE
|
|
107
|
-
# DM Adapter dependent
|
|
108
|
-
def get_current_users
|
|
109
|
-
unless self.repository.adapter.is_a?(::DataMapper::Adapters::MysqlAdapter)
|
|
110
|
-
raise 'Unsupported DataMapper Adapter'
|
|
111
|
-
end
|
|
112
|
-
config = sorcery_config
|
|
113
|
-
ret = all(config.last_logout_at_attribute_name => nil) |
|
|
114
|
-
all(config.last_activity_at_attribute_name.gt => config.last_logout_at_attribute_name)
|
|
115
|
-
ret = ret.all(config.last_activity_at_attribute_name.not => nil)
|
|
116
|
-
ret = ret.all(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc)
|
|
117
|
-
ret
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
module Sorcery
|
|
2
|
-
module Model
|
|
3
|
-
module Adapters
|
|
4
|
-
module MongoMapper
|
|
5
|
-
extend ActiveSupport::Concern
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
extend Sorcery::Model
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def increment(attr)
|
|
12
|
-
self.class.increment(id, attr => 1)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def sorcery_save(options = {})
|
|
16
|
-
if options.delete(:raise_on_failure) && options[:validate] != false
|
|
17
|
-
save! options
|
|
18
|
-
else
|
|
19
|
-
save options
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def update_many_attributes(attrs)
|
|
24
|
-
update_attributes(attrs)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
module ClassMethods
|
|
28
|
-
def credential_regex(credential)
|
|
29
|
-
return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
|
30
|
-
return credential
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def find_by_credentials(credentials)
|
|
34
|
-
@sorcery_config.username_attribute_names.each do |attribute|
|
|
35
|
-
@user = where(attribute => credential_regex(credentials[0])).first
|
|
36
|
-
break if @user
|
|
37
|
-
end
|
|
38
|
-
@user
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def find_by_id(id)
|
|
42
|
-
find(id)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def find_by_activation_token(token)
|
|
46
|
-
where(sorcery_config.activation_token_attribute_name => token).first
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def transaction(&blk)
|
|
50
|
-
tap(&blk)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def find_by_sorcery_token(token_attr_name, token)
|
|
54
|
-
where(token_attr_name => token).first
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
module Sorcery
|
|
2
|
-
module Model
|
|
3
|
-
module Adapters
|
|
4
|
-
module Mongoid
|
|
5
|
-
module InstanceMethods
|
|
6
|
-
def increment(attr)
|
|
7
|
-
self.inc(attr, 1)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def update_many_attributes(attrs)
|
|
11
|
-
attrs.each do |name, value|
|
|
12
|
-
attrs[name] = value.utc if value.is_a?(ActiveSupport::TimeWithZone)
|
|
13
|
-
self.send(:"#{name}=", value)
|
|
14
|
-
end
|
|
15
|
-
self.class.where(:_id => self.id).update_all(attrs)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def update_single_attribute(name, value)
|
|
19
|
-
update_many_attributes(name => value)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def sorcery_save(options = {})
|
|
23
|
-
mthd = options.delete(:raise_on_failure) ? :save! : :save
|
|
24
|
-
self.send(mthd, options)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
module ClassMethods
|
|
29
|
-
def credential_regex(credential)
|
|
30
|
-
return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
|
31
|
-
credential
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def find_by_credentials(credentials)
|
|
35
|
-
@sorcery_config.username_attribute_names.each do |attribute|
|
|
36
|
-
@user = where(attribute => credential_regex(credentials[0])).first
|
|
37
|
-
break if @user
|
|
38
|
-
end
|
|
39
|
-
@user
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def find_by_provider_and_uid(provider, uid)
|
|
43
|
-
@user_klass ||= ::Sorcery::Controller::Config.user_class.to_s.constantize
|
|
44
|
-
where(@user_klass.sorcery_config.provider_attribute_name => provider, @user_klass.sorcery_config.provider_uid_attribute_name => uid).first
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def find_by_id(id)
|
|
48
|
-
find(id)
|
|
49
|
-
rescue ::Mongoid::Errors::DocumentNotFound
|
|
50
|
-
nil
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def find_by_activation_token(token)
|
|
54
|
-
where(sorcery_config.activation_token_attribute_name => token).first
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def find_by_remember_me_token(token)
|
|
58
|
-
where(sorcery_config.remember_me_token_attribute_name => token).first
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def find_by_username(username)
|
|
62
|
-
query = sorcery_config.username_attribute_names.map {|name| {name => username}}
|
|
63
|
-
any_of(*query).first
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def transaction(&blk)
|
|
67
|
-
tap(&blk)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def find_by_sorcery_token(token_attr_name, token)
|
|
71
|
-
where(token_attr_name => token).first
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def find_by_email(email)
|
|
75
|
-
where(sorcery_config.email_attribute_name => email).first
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def get_current_users
|
|
79
|
-
config = sorcery_config
|
|
80
|
-
where(config.last_activity_at_attribute_name.ne => nil) \
|
|
81
|
-
.where("this.#{config.last_logout_at_attribute_name} == null || this.#{config.last_activity_at_attribute_name} > this.#{config.last_logout_at_attribute_name}") \
|
|
82
|
-
.where(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc).order_by([:_id,:asc])
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'shared_examples/controller_activity_logging_shared_examples'
|
|
4
|
-
|
|
5
|
-
describe SorceryController, :active_record => true do
|
|
6
|
-
before(:all) do
|
|
7
|
-
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging")
|
|
8
|
-
User.reset_column_information
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
after(:all) do
|
|
12
|
-
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activity_logging")
|
|
13
|
-
|
|
14
|
-
sorcery_controller_property_set(:register_login_time, true)
|
|
15
|
-
sorcery_controller_property_set(:register_logout_time, true)
|
|
16
|
-
sorcery_controller_property_set(:register_last_activity_time, true)
|
|
17
|
-
# sorcery_controller_property_set(:last_login_from_ip_address_name, true)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# ----------------- ACTIVITY LOGGING -----------------------
|
|
21
|
-
context "with activity logging features" do
|
|
22
|
-
after(:each) do
|
|
23
|
-
User.delete_all
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it_behaves_like "controller_activity_logging"
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe SorceryController, :active_record => true do
|
|
4
|
-
|
|
5
|
-
let(:db_user) { User.find_by_email 'bla@bla.com' }
|
|
6
|
-
let!(:user) { create_new_user }
|
|
7
|
-
|
|
8
|
-
def request_test_login
|
|
9
|
-
get :test_login, :email => 'bla@bla.com', :password => 'blabla'
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
before(:all) do
|
|
13
|
-
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
|
|
14
|
-
User.reset_column_information
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
after(:all) do
|
|
18
|
-
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# ----------------- SESSION TIMEOUT -----------------------
|
|
22
|
-
describe "brute force protection features" do
|
|
23
|
-
|
|
24
|
-
before(:all) do
|
|
25
|
-
sorcery_reload!([:brute_force_protection])
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
after(:each) do
|
|
30
|
-
Sorcery::Controller::Config.reset!
|
|
31
|
-
sorcery_controller_property_set(:user_class, User)
|
|
32
|
-
Timecop.return
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "counts login retries" do
|
|
36
|
-
3.times { request_test_login }
|
|
37
|
-
expect(db_user.failed_logins_count).to eq 3
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "generates unlock token before mail is sent" do
|
|
41
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
42
|
-
sorcery_model_property_set(:login_lock_time_period, 0)
|
|
43
|
-
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
|
44
|
-
3.times { request_test_login }
|
|
45
|
-
expect(ActionMailer::Base.deliveries.last.body.to_s.match(db_user.unlock_token)).not_to be_nil
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "unlocks after entering unlock token" do
|
|
49
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
50
|
-
sorcery_model_property_set(:login_lock_time_period, 0)
|
|
51
|
-
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
|
52
|
-
3.times { request_test_login }
|
|
53
|
-
|
|
54
|
-
expect(db_user.unlock_token).not_to be_nil
|
|
55
|
-
|
|
56
|
-
token = db_user.unlock_token
|
|
57
|
-
user = User.load_from_unlock_token(token)
|
|
58
|
-
|
|
59
|
-
expect(user).not_to be_nil
|
|
60
|
-
|
|
61
|
-
user.unlock!
|
|
62
|
-
expect(User.load_from_unlock_token(db_user.unlock_token)).to be_nil
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "resets the counter on a good login" do
|
|
66
|
-
# dirty hack for rails 4
|
|
67
|
-
allow(@controller).to receive(:register_last_activity_time_to_db)
|
|
68
|
-
|
|
69
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 5)
|
|
70
|
-
3.times { request_test_login }
|
|
71
|
-
get :test_login, :email => 'bla@bla.com', :password => 'secret'
|
|
72
|
-
|
|
73
|
-
expect(db_user.failed_logins_count).to eq 0
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "locks user when number of retries reached the limit" do
|
|
77
|
-
expect(db_user.lock_expires_at).to be_nil
|
|
78
|
-
|
|
79
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
|
|
80
|
-
request_test_login
|
|
81
|
-
|
|
82
|
-
expect(db_user.reload.lock_expires_at).not_to be_nil
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "unlocks after lock time period passes" do
|
|
86
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
87
|
-
sorcery_model_property_set(:login_lock_time_period, 0.2)
|
|
88
|
-
2.times { request_test_login }
|
|
89
|
-
|
|
90
|
-
expect(db_user.reload.lock_expires_at).not_to be_nil
|
|
91
|
-
|
|
92
|
-
Timecop.travel(Time.now.in_time_zone + 0.3)
|
|
93
|
-
request_test_login
|
|
94
|
-
|
|
95
|
-
expect(db_user.reload.lock_expires_at).to be_nil
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it "doest not unlock if time period is 0 (permanent lock)" do
|
|
99
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
100
|
-
sorcery_model_property_set(:login_lock_time_period, 0)
|
|
101
|
-
2.times { request_test_login }
|
|
102
|
-
unlock_date = db_user.lock_expires_at
|
|
103
|
-
Timecop.travel(Time.now.in_time_zone + 1)
|
|
104
|
-
request_test_login
|
|
105
|
-
|
|
106
|
-
expect(db_user.lock_expires_at.to_s).to eq unlock_date.to_s
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
context "unlock_token_mailer_disabled is true" do
|
|
110
|
-
|
|
111
|
-
before(:each) do
|
|
112
|
-
sorcery_model_property_set(:unlock_token_mailer_disabled, true)
|
|
113
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
114
|
-
sorcery_model_property_set(:login_lock_time_period, 0)
|
|
115
|
-
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it "generates unlock token after user locked" do
|
|
119
|
-
3.times { request_test_login }
|
|
120
|
-
|
|
121
|
-
expect(db_user.unlock_token).not_to be_nil
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "doest *not* automatically send unlock mail" do
|
|
125
|
-
old_size = ActionMailer::Base.deliveries.size
|
|
126
|
-
3.times { request_test_login }
|
|
127
|
-
|
|
128
|
-
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
context "unlock_token_mailer_disabled is false" do
|
|
134
|
-
|
|
135
|
-
before(:each) do
|
|
136
|
-
sorcery_model_property_set(:unlock_token_mailer_disabled, false)
|
|
137
|
-
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
|
138
|
-
sorcery_model_property_set(:login_lock_time_period, 0)
|
|
139
|
-
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
it "sets the unlock token after user locked" do
|
|
143
|
-
3.times { request_test_login }
|
|
144
|
-
|
|
145
|
-
expect(db_user.unlock_token).not_to be_nil
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
it "automatically sends unlock mail" do
|
|
149
|
-
old_size = ActionMailer::Base.deliveries.size
|
|
150
|
-
3.times { request_test_login }
|
|
151
|
-
|
|
152
|
-
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
end
|
|
158
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe "the login process", :type => :request, :active_record => true do
|
|
4
|
-
before(:all) do
|
|
5
|
-
sorcery_reload!
|
|
6
|
-
create_new_user
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
after(:all) do
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
# it "handles unverified request", :js => true do
|
|
13
|
-
# visit root_path
|
|
14
|
-
# #save_and_open_page
|
|
15
|
-
# fill_in 'Username', :with => 'gizmo1'
|
|
16
|
-
# fill_in 'Password', :with => 'secret'
|
|
17
|
-
# # <input name="authenticity_token" type="hidden" value="+8M9lXnjnhAW/mAuzwI9Mmy6hM+00qZJa8VMQUg+NmM=">
|
|
18
|
-
# page.execute_script("$$('hidden').value='mezuza'")
|
|
19
|
-
# #save_and_open_page
|
|
20
|
-
# click_button 'Login'
|
|
21
|
-
# save_and_open_page
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'shared_examples/controller_activity_logging_shared_examples'
|
|
3
|
-
|
|
4
|
-
describe SorceryController, :datamapper => true do
|
|
5
|
-
|
|
6
|
-
# ----------------- ACTIVITY LOGGING -----------------------
|
|
7
|
-
context "with activity logging features" do
|
|
8
|
-
after(:each) do
|
|
9
|
-
# NOTE dm-constraints supports only pg and mysql
|
|
10
|
-
Authentication.all.destroy
|
|
11
|
-
User.delete_all
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it_behaves_like "controller_activity_logging"
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'shared_examples/controller_activity_logging_shared_examples'
|
|
3
|
-
|
|
4
|
-
describe SorceryController, :mongoid => true do
|
|
5
|
-
|
|
6
|
-
# ----------------- ACTIVITY LOGGING -----------------------
|
|
7
|
-
context "with activity logging features" do
|
|
8
|
-
after(:each) do
|
|
9
|
-
User.delete_all
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
it_behaves_like "controller_activity_logging"
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
-
<style type="text/css">
|
|
6
|
-
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
-
div.dialog {
|
|
8
|
-
width: 25em;
|
|
9
|
-
padding: 0 4em;
|
|
10
|
-
margin: 4em auto 0 auto;
|
|
11
|
-
border: 1px solid #ccc;
|
|
12
|
-
border-right-color: #999;
|
|
13
|
-
border-bottom-color: #999;
|
|
14
|
-
}
|
|
15
|
-
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<!-- This file lives in public/404.html -->
|
|
21
|
-
<div class="dialog">
|
|
22
|
-
<h1>The page you were looking for doesn't exist.</h1>
|
|
23
|
-
<p>You may have mistyped the address or the page may have moved.</p>
|
|
24
|
-
</div>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>The change you wanted was rejected (422)</title>
|
|
5
|
-
<style type="text/css">
|
|
6
|
-
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
-
div.dialog {
|
|
8
|
-
width: 25em;
|
|
9
|
-
padding: 0 4em;
|
|
10
|
-
margin: 4em auto 0 auto;
|
|
11
|
-
border: 1px solid #ccc;
|
|
12
|
-
border-right-color: #999;
|
|
13
|
-
border-bottom-color: #999;
|
|
14
|
-
}
|
|
15
|
-
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<!-- This file lives in public/422.html -->
|
|
21
|
-
<div class="dialog">
|
|
22
|
-
<h1>The change you wanted was rejected.</h1>
|
|
23
|
-
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
-
</div>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
-
<style type="text/css">
|
|
6
|
-
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
-
div.dialog {
|
|
8
|
-
width: 25em;
|
|
9
|
-
padding: 0 4em;
|
|
10
|
-
margin: 4em auto 0 auto;
|
|
11
|
-
border: 1px solid #ccc;
|
|
12
|
-
border-right-color: #999;
|
|
13
|
-
border-bottom-color: #999;
|
|
14
|
-
}
|
|
15
|
-
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<!-- This file lives in public/500.html -->
|
|
21
|
-
<div class="dialog">
|
|
22
|
-
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
-
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
|
24
|
-
</div>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
|
File without changes
|
|
Binary file
|