sorcery 0.8.5 → 0.8.6
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +60 -4
- data/CHANGELOG.md +15 -1
- data/Gemfile +9 -18
- data/Gemfile.rails4 +8 -10
- data/README.md +31 -11
- data/VERSION +1 -1
- data/gemfiles/active_record-rails41.gemfile +6 -0
- data/gemfiles/mongo_mapper-rails41.gemfile +8 -0
- data/gemfiles/mongoid-rails41.gemfile +11 -0
- data/lib/sorcery.rb +20 -28
- data/lib/sorcery/controller.rb +6 -11
- data/lib/sorcery/controller/submodules/external.rb +30 -15
- data/lib/sorcery/controller/submodules/session_timeout.rb +1 -1
- data/lib/sorcery/model.rb +102 -70
- data/lib/sorcery/model/adapters/active_record.rb +7 -2
- data/lib/sorcery/model/adapters/datamapper.rb +123 -0
- data/lib/sorcery/model/adapters/mongo_mapper.rb +8 -4
- data/lib/sorcery/model/adapters/mongoid.rb +6 -6
- data/lib/sorcery/model/submodules/activity_logging.rb +24 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +16 -0
- data/lib/sorcery/model/submodules/remember_me.rb +19 -4
- data/lib/sorcery/model/submodules/reset_password.rb +30 -13
- data/lib/sorcery/model/submodules/user_activation.rb +53 -22
- data/lib/sorcery/{controller/submodules/external/protocols → protocols}/certs/ca-bundle.crt +0 -0
- data/lib/sorcery/protocols/oauth.rb +42 -0
- data/lib/sorcery/protocols/oauth2.rb +47 -0
- data/lib/sorcery/providers/base.rb +27 -0
- data/lib/sorcery/providers/facebook.rb +63 -0
- data/lib/sorcery/providers/github.rb +51 -0
- data/lib/sorcery/providers/google.rb +51 -0
- data/lib/sorcery/providers/linkedin.rb +66 -0
- data/lib/sorcery/providers/liveid.rb +53 -0
- data/lib/sorcery/providers/twitter.rb +59 -0
- data/lib/sorcery/providers/vk.rb +61 -0
- data/lib/sorcery/providers/xing.rb +64 -0
- data/lib/sorcery/test_helpers/internal.rb +3 -3
- data/lib/sorcery/test_helpers/internal/rails.rb +14 -3
- data/lib/sorcery/test_helpers/rails.rb +1 -10
- data/lib/sorcery/test_helpers/rails/controller.rb +17 -0
- data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
- data/sorcery.gemspec +14 -18
- data/spec/active_record/controller_activity_logging_spec.rb +5 -116
- data/spec/active_record/controller_brute_force_protection_spec.rb +69 -47
- data/spec/active_record/controller_http_basic_auth_spec.rb +24 -18
- data/spec/active_record/controller_oauth2_spec.rb +112 -187
- data/spec/active_record/controller_oauth_spec.rb +41 -37
- data/spec/active_record/controller_remember_me_spec.rb +39 -38
- data/spec/active_record/controller_session_timeout_spec.rb +31 -16
- data/spec/active_record/controller_spec.rb +4 -178
- data/spec/active_record/integration_spec.rb +1 -1
- data/spec/active_record/user_activation_spec.rb +1 -1
- data/spec/active_record/user_activity_logging_spec.rb +1 -1
- data/spec/active_record/user_brute_force_protection_spec.rb +1 -1
- data/spec/active_record/user_oauth_spec.rb +1 -1
- data/spec/active_record/user_remember_me_spec.rb +1 -1
- data/spec/active_record/user_reset_password_spec.rb +1 -1
- data/spec/active_record/user_spec.rb +7 -8
- data/spec/datamapper/controller_activity_logging_spec.rb +17 -0
- data/spec/datamapper/controller_spec.rb +8 -0
- data/spec/datamapper/user_activation_spec.rb +10 -0
- data/spec/datamapper/user_activity_logging_spec.rb +9 -0
- data/spec/datamapper/user_brute_force_protection_spec.rb +9 -0
- data/spec/datamapper/user_oauth_spec.rb +9 -0
- data/spec/datamapper/user_remember_me_spec.rb +8 -0
- data/spec/datamapper/user_reset_password_spec.rb +8 -0
- data/spec/datamapper/user_spec.rb +27 -0
- data/spec/mongo_mapper/controller_spec.rb +4 -171
- data/spec/mongo_mapper/user_activation_spec.rb +1 -2
- data/spec/mongo_mapper/user_activity_logging_spec.rb +1 -1
- data/spec/mongo_mapper/user_brute_force_protection_spec.rb +1 -1
- data/spec/mongo_mapper/user_oauth_spec.rb +1 -1
- data/spec/mongo_mapper/user_remember_me_spec.rb +1 -1
- data/spec/mongo_mapper/user_reset_password_spec.rb +1 -1
- data/spec/mongo_mapper/user_spec.rb +7 -8
- data/spec/mongoid/controller_activity_logging_spec.rb +4 -99
- data/spec/mongoid/controller_spec.rb +4 -182
- data/spec/mongoid/user_activation_spec.rb +1 -2
- data/spec/mongoid/user_activity_logging_spec.rb +1 -2
- data/spec/mongoid/user_brute_force_protection_spec.rb +1 -2
- data/spec/mongoid/user_oauth_spec.rb +1 -2
- data/spec/mongoid/user_remember_me_spec.rb +1 -2
- data/spec/mongoid/user_reset_password_spec.rb +1 -2
- data/spec/mongoid/user_spec.rb +8 -9
- data/spec/orm/active_record.rb +2 -0
- data/spec/orm/datamapper.rb +34 -0
- data/spec/orm/mongo_mapper.rb +1 -0
- data/spec/orm/mongoid.rb +1 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +64 -59
- data/spec/rails_app/app/datamapper/authentication.rb +8 -0
- data/spec/rails_app/app/datamapper/user.rb +7 -0
- data/spec/rails_app/config/routes.rb +18 -13
- data/spec/shared_examples/controller_activity_logging_shared_examples.rb +125 -0
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +32 -36
- data/spec/shared_examples/controller_oauth_shared_examples.rb +19 -26
- data/spec/shared_examples/controller_shared_examples.rb +203 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +107 -90
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +10 -10
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +14 -13
- data/spec/shared_examples/user_oauth_shared_examples.rb +23 -15
- data/spec/shared_examples/user_remember_me_shared_examples.rb +32 -23
- data/spec/shared_examples/user_reset_password_shared_examples.rb +136 -115
- data/spec/shared_examples/user_shared_examples.rb +206 -146
- data/spec/sorcery_crypto_providers_spec.rb +28 -28
- data/spec/spec_helper.rb +15 -6
- metadata +83 -127
- data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +0 -46
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +0 -50
- data/lib/sorcery/controller/submodules/external/providers/base.rb +0 -21
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +0 -99
- data/lib/sorcery/controller/submodules/external/providers/github.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/google.rb +0 -92
- data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +0 -103
- data/lib/sorcery/controller/submodules/external/providers/liveid.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/twitter.rb +0 -94
- data/lib/sorcery/controller/submodules/external/providers/vk.rb +0 -101
- data/lib/sorcery/controller/submodules/external/providers/xing.rb +0 -98
- data/lib/sorcery/test_helpers.rb +0 -5
@@ -37,7 +37,7 @@ module Sorcery
|
|
37
37
|
# To be used as a before_filter, before require_login
|
38
38
|
def validate_session
|
39
39
|
session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time]
|
40
|
-
if session_to_use && (Time.now.in_time_zone - session_to_use > Config.session_timeout)
|
40
|
+
if session_to_use && (Time.now.in_time_zone - session_to_use.to_time > Config.session_timeout)
|
41
41
|
reset_sorcery_session
|
42
42
|
@current_user = nil
|
43
43
|
else
|
data/lib/sorcery/model.rb
CHANGED
@@ -7,86 +7,114 @@ module Sorcery
|
|
7
7
|
# which when called adds the other capabilities to the class.
|
8
8
|
# This method is also the place to configure the plugin in the Model layer.
|
9
9
|
module Model
|
10
|
-
def
|
11
|
-
|
12
|
-
class << self
|
13
|
-
def authenticates_with_sorcery!
|
14
|
-
@sorcery_config = Config.new
|
15
|
-
self.class_eval do
|
16
|
-
extend ClassMethods # included here, before submodules, so they can be overriden by them.
|
17
|
-
include InstanceMethods
|
18
|
-
include TemporaryToken
|
19
|
-
end
|
10
|
+
def authenticates_with_sorcery!
|
11
|
+
@sorcery_config = Config.new
|
20
12
|
|
21
|
-
|
13
|
+
extend ClassMethods # included here, before submodules, so they can be overriden by them.
|
14
|
+
include InstanceMethods
|
15
|
+
include TemporaryToken
|
22
16
|
|
23
|
-
|
24
|
-
::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
|
17
|
+
include_required_submodules!
|
25
18
|
|
26
|
-
|
27
|
-
|
19
|
+
# This runs the options block set in the initializer on the model class.
|
20
|
+
::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
|
28
21
|
|
29
|
-
|
22
|
+
init_mongoid_support! if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
|
23
|
+
init_mongo_mapper_support! if defined?(MongoMapper) and self.ancestors.include?(MongoMapper::Document)
|
24
|
+
init_datamapper_support! if defined?(DataMapper) and self.ancestors.include?(DataMapper::Resource)
|
30
25
|
|
31
|
-
|
32
|
-
@sorcery_config.after_config.each { |c| send(c) }
|
33
|
-
end
|
26
|
+
init_orm_hooks!
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# which usually is called User.
|
39
|
-
def include_required_submodules!
|
40
|
-
self.class_eval do
|
41
|
-
@sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
|
42
|
-
@sorcery_config.submodules.each do |mod|
|
43
|
-
begin
|
44
|
-
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
45
|
-
rescue NameError
|
46
|
-
# don't stop on a missing submodule. Needed because some submodules are only defined
|
47
|
-
# in the controller side.
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
28
|
+
@sorcery_config.after_config << :add_config_inheritance if @sorcery_config.subclasses_inherit_config
|
29
|
+
@sorcery_config.after_config.each { |c| send(c) }
|
30
|
+
end
|
52
31
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
32
|
+
protected
|
33
|
+
|
34
|
+
# includes required submodules into the model class,
|
35
|
+
# which usually is called User.
|
36
|
+
def include_required_submodules!
|
37
|
+
self.class_eval do
|
38
|
+
@sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
|
39
|
+
@sorcery_config.submodules.each do |mod|
|
40
|
+
begin
|
41
|
+
include Submodules.const_get(mod.to_s.split('_').map {|p| p.capitalize}.join)
|
42
|
+
rescue NameError
|
43
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined
|
44
|
+
# in the controller side.
|
64
45
|
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
65
49
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
50
|
+
# defines mongoid fields on the model class,
|
51
|
+
# using 1.8.x hash syntax to perserve compatibility.
|
52
|
+
def init_mongoid_support!
|
53
|
+
self.class_eval do
|
54
|
+
sorcery_config.username_attribute_names.each do |username|
|
55
|
+
field username, :type => String
|
56
|
+
end
|
57
|
+
field sorcery_config.email_attribute_name, :type => String unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
|
58
|
+
field sorcery_config.crypted_password_attribute_name, :type => String
|
59
|
+
field sorcery_config.salt_attribute_name, :type => String
|
60
|
+
end
|
61
|
+
end
|
77
62
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
63
|
+
# defines mongo_mapper fields on the model class,
|
64
|
+
def init_mongo_mapper_support!
|
65
|
+
self.class_eval do
|
66
|
+
sorcery_config.username_attribute_names.each do |username|
|
67
|
+
key username, String
|
68
|
+
end
|
69
|
+
key sorcery_config.email_attribute_name, String unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
|
70
|
+
key sorcery_config.crypted_password_attribute_name, String
|
71
|
+
key sorcery_config.salt_attribute_name, String
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# defines datamapper fields on the model class
|
76
|
+
def init_datamapper_support!
|
77
|
+
self.class_eval do
|
78
|
+
sorcery_config.username_attribute_names.each do |username|
|
79
|
+
property username, String, :length => 255
|
80
|
+
end
|
81
|
+
unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
|
82
|
+
property sorcery_config.email_attribute_name, String, :length => 255
|
83
|
+
end
|
84
|
+
property sorcery_config.crypted_password_attribute_name, String, :length => 255
|
85
|
+
property sorcery_config.salt_attribute_name, String, :length => 255
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# add virtual password accessor and ORM callbacks.
|
90
|
+
def init_orm_hooks!
|
91
|
+
if defined?(DataMapper) and self.ancestors.include?(DataMapper::Resource)
|
92
|
+
init_datamapper_hooks!
|
93
|
+
return
|
94
|
+
end
|
95
|
+
self.class_eval do
|
96
|
+
attr_accessor @sorcery_config.password_attribute_name
|
97
|
+
#attr_protected @sorcery_config.crypted_password_attribute_name, @sorcery_config.salt_attribute_name
|
98
|
+
before_save :encrypt_password, :if => Proc.new { |record|
|
99
|
+
record.send(sorcery_config.password_attribute_name).present?
|
100
|
+
}
|
101
|
+
after_save :clear_virtual_password, :if => Proc.new { |record|
|
102
|
+
record.send(sorcery_config.password_attribute_name).present?
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def init_datamapper_hooks!
|
108
|
+
self.class_eval do
|
109
|
+
attr_accessor @sorcery_config.password_attribute_name
|
110
|
+
before :valid? do
|
111
|
+
if self.send(sorcery_config.password_attribute_name).present?
|
112
|
+
encrypt_password
|
113
|
+
end
|
114
|
+
end
|
115
|
+
after :save do
|
116
|
+
if self.send(sorcery_config.password_attribute_name).present?
|
117
|
+
clear_virtual_password
|
90
118
|
end
|
91
119
|
end
|
92
120
|
end
|
@@ -183,6 +211,10 @@ module Sorcery
|
|
183
211
|
def clear_virtual_password
|
184
212
|
config = sorcery_config
|
185
213
|
self.send(:"#{config.password_attribute_name}=", nil)
|
214
|
+
|
215
|
+
if respond_to?(:"#{config.password_attribute_name}_confirmation=")
|
216
|
+
self.send(:"#{config.password_attribute_name}_confirmation=", nil)
|
217
|
+
end
|
186
218
|
end
|
187
219
|
|
188
220
|
# calls the requested email method on the configured mailer
|
@@ -19,12 +19,17 @@ module Sorcery
|
|
19
19
|
def update_single_attribute(name, value)
|
20
20
|
update_many_attributes(name => value)
|
21
21
|
end
|
22
|
+
|
23
|
+
def sorcery_save(options = {})
|
24
|
+
mthd = options.delete(:raise_on_failure) ? :save! : :save
|
25
|
+
self.send(mthd, options)
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
29
|
module ClassMethods
|
25
30
|
def column_name(attribute)
|
26
31
|
return "LOWER(#{attribute})" if (@sorcery_config.downcase_username_before_authenticating)
|
27
|
-
|
32
|
+
attribute.to_s
|
28
33
|
end
|
29
34
|
|
30
35
|
def find_by_credentials(credentials)
|
@@ -37,7 +42,7 @@ module Sorcery
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def get_current_users
|
40
|
-
config = sorcery_config
|
45
|
+
config = @sorcery_config
|
41
46
|
where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
|
42
47
|
.where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
|
43
48
|
.where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
|
@@ -0,0 +1,123 @@
|
|
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
|
@@ -5,15 +5,19 @@ module Sorcery
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
8
|
+
extend Sorcery::Model
|
9
9
|
end
|
10
10
|
|
11
11
|
def increment(attr)
|
12
12
|
self.class.increment(id, attr => 1)
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
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
|
17
21
|
end
|
18
22
|
|
19
23
|
def update_many_attributes(attrs)
|
@@ -22,7 +26,7 @@ module Sorcery
|
|
22
26
|
|
23
27
|
module ClassMethods
|
24
28
|
def credential_regex(credential)
|
25
|
-
return { :$regex => /^#{credential}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
29
|
+
return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
26
30
|
return credential
|
27
31
|
end
|
28
32
|
|
@@ -2,11 +2,6 @@ module Sorcery
|
|
2
2
|
module Model
|
3
3
|
module Adapters
|
4
4
|
module Mongoid
|
5
|
-
def self.included(klass)
|
6
|
-
klass.extend ClassMethods
|
7
|
-
klass.send(:include, InstanceMethods)
|
8
|
-
end
|
9
|
-
|
10
5
|
module InstanceMethods
|
11
6
|
def increment(attr)
|
12
7
|
self.inc(attr, 1)
|
@@ -23,11 +18,16 @@ module Sorcery
|
|
23
18
|
def update_single_attribute(name, value)
|
24
19
|
update_many_attributes(name => value)
|
25
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
26
|
end
|
27
27
|
|
28
28
|
module ClassMethods
|
29
29
|
def credential_regex(credential)
|
30
|
-
return { :$regex => /^#{credential}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
30
|
+
return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
|
31
31
|
credential
|
32
32
|
end
|
33
33
|
|
@@ -29,6 +29,13 @@ module Sorcery
|
|
29
29
|
end
|
30
30
|
|
31
31
|
base.sorcery_config.after_config << :define_activity_logging_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
32
|
+
if defined?(DataMapper) and base.ancestors.include?(DataMapper::Resource)
|
33
|
+
# NOTE raise exception if data-store is not supported
|
34
|
+
unless base.repository.adapter.is_a?(DataMapper::Adapters::MysqlAdapter)
|
35
|
+
raise 'Unsupported DataMapper Adapter'
|
36
|
+
end
|
37
|
+
base.sorcery_config.after_config << :define_activity_logging_datamapper_fields
|
38
|
+
end
|
32
39
|
end
|
33
40
|
|
34
41
|
module ClassMethods
|
@@ -46,6 +53,23 @@ module Sorcery
|
|
46
53
|
field sorcery_config.last_activity_at_attribute_name, :type => Time
|
47
54
|
field sorcery_config.last_login_from_ip_address_name, :type => String
|
48
55
|
end
|
56
|
+
|
57
|
+
def define_activity_logging_datamapper_fields
|
58
|
+
property sorcery_config.last_login_at_attribute_name, Time
|
59
|
+
property sorcery_config.last_logout_at_attribute_name, Time
|
60
|
+
property sorcery_config.last_activity_at_attribute_name, Time
|
61
|
+
property sorcery_config.last_login_from_ip_address_name, String
|
62
|
+
# Workaround local timezone retrieval problem NOTE dm-core issue #193
|
63
|
+
[sorcery_config.last_login_at_attribute_name,
|
64
|
+
sorcery_config.last_logout_at_attribute_name,
|
65
|
+
sorcery_config.last_activity_at_attribute_name].each do |sym|
|
66
|
+
alias_method "orig_#{sym}", sym
|
67
|
+
define_method(sym) do
|
68
|
+
t = send("orig_#{sym}")
|
69
|
+
t && Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec, 0)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
49
73
|
end
|
50
74
|
end
|
51
75
|
end
|