sorcery 0.8.6 → 0.9.0
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 +2 -1
- data/.travis.yml +75 -14
- data/CHANGELOG.md +23 -1
- data/Gemfile +1 -0
- data/README.md +137 -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 +34 -9
- 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.rb +75 -43
- 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.rb +5 -64
- 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 +8 -28
- data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
- data/lib/sorcery/model.rb +43 -175
- 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/providers/base.rb +11 -0
- data/lib/sorcery/providers/facebook.rb +1 -1
- data/lib/sorcery/providers/github.rb +1 -1
- 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 +1 -1
- 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/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 +128 -56
- 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/{datamapper → data_mapper}/authentication.rb +0 -0
- data/spec/rails_app/app/{datamapper → data_mapper}/user.rb +0 -0
- 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 +117 -30
- data/spec/spec_helper.rb +7 -22
- metadata +36 -58
- 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
@@ -0,0 +1,96 @@
|
|
1
|
+
# Each class which calls 'activate_sorcery!' receives an instance of this class.
|
2
|
+
# Every submodule which gets loaded may add accessors to this class so that all
|
3
|
+
# options will be configured from a single place.
|
4
|
+
module Sorcery
|
5
|
+
module Model
|
6
|
+
class Config
|
7
|
+
|
8
|
+
attr_accessor :username_attribute_names, # change default username attribute, for example, to use :email
|
9
|
+
# as the login.
|
10
|
+
|
11
|
+
:password_attribute_name, # change *virtual* password attribute, the one which is used
|
12
|
+
# until an encrypted one is generated.
|
13
|
+
|
14
|
+
:email_attribute_name, # change default email attribute.
|
15
|
+
|
16
|
+
:downcase_username_before_authenticating, # downcase the username before trying to authenticate, default is false
|
17
|
+
|
18
|
+
:crypted_password_attribute_name, # change default crypted_password attribute.
|
19
|
+
:salt_join_token, # what pattern to use to join the password with the salt
|
20
|
+
:salt_attribute_name, # change default salt attribute.
|
21
|
+
:stretches, # how many times to apply encryption to the password.
|
22
|
+
:encryption_key, # encryption key used to encrypt reversible encryptions such as
|
23
|
+
# AES256.
|
24
|
+
|
25
|
+
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for
|
26
|
+
# ActiveRecord's STI.
|
27
|
+
|
28
|
+
:submodules, # configured in config/application.rb
|
29
|
+
:before_authenticate, # an array of method names to call before authentication
|
30
|
+
# completes. used internally.
|
31
|
+
|
32
|
+
:after_config # an array of method names to call after configuration by user.
|
33
|
+
# used internally.
|
34
|
+
|
35
|
+
attr_reader :encryption_provider, # change default encryption_provider.
|
36
|
+
:custom_encryption_provider, # use an external encryption class.
|
37
|
+
:encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
|
38
|
+
# for available options.
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@defaults = {
|
42
|
+
:@submodules => [],
|
43
|
+
:@username_attribute_names => [:email],
|
44
|
+
:@password_attribute_name => :password,
|
45
|
+
:@downcase_username_before_authenticating => false,
|
46
|
+
:@email_attribute_name => :email,
|
47
|
+
:@crypted_password_attribute_name => :crypted_password,
|
48
|
+
:@encryption_algorithm => :bcrypt,
|
49
|
+
:@encryption_provider => CryptoProviders::BCrypt,
|
50
|
+
:@custom_encryption_provider => nil,
|
51
|
+
:@encryption_key => nil,
|
52
|
+
:@salt_join_token => "",
|
53
|
+
:@salt_attribute_name => :salt,
|
54
|
+
:@stretches => nil,
|
55
|
+
:@subclasses_inherit_config => false,
|
56
|
+
:@before_authenticate => [],
|
57
|
+
:@after_config => []
|
58
|
+
}
|
59
|
+
reset!
|
60
|
+
end
|
61
|
+
|
62
|
+
# Resets all configuration options to their default values.
|
63
|
+
def reset!
|
64
|
+
@defaults.each do |k,v|
|
65
|
+
instance_variable_set(k,v)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def username_attribute_names=(fields)
|
70
|
+
@username_attribute_names = fields.kind_of?(Array) ? fields : [fields]
|
71
|
+
end
|
72
|
+
|
73
|
+
def custom_encryption_provider=(provider)
|
74
|
+
@custom_encryption_provider = @encryption_provider = provider
|
75
|
+
end
|
76
|
+
|
77
|
+
def encryption_algorithm=(algo)
|
78
|
+
@encryption_algorithm = algo
|
79
|
+
@encryption_provider = case @encryption_algorithm.to_sym
|
80
|
+
when :none then nil
|
81
|
+
when :md5 then CryptoProviders::MD5
|
82
|
+
when :sha1 then CryptoProviders::SHA1
|
83
|
+
when :sha256 then CryptoProviders::SHA256
|
84
|
+
when :sha512 then CryptoProviders::SHA512
|
85
|
+
when :aes256 then CryptoProviders::AES256
|
86
|
+
when :bcrypt then CryptoProviders::BCrypt
|
87
|
+
when :custom then @custom_encryption_provider
|
88
|
+
else raise ArgumentError.new("Encryption algorithm supplied, #{algo}, is invalid")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
@@ -3,22 +3,23 @@ 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
|
6
|
+
# This cannot be determined absolutely because a user might be reading a page without clicking anything
|
7
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)
|
11
11
|
base.extend(ClassMethods)
|
12
|
+
base.send(:include, InstanceMethods)
|
12
13
|
|
13
14
|
base.sorcery_config.class_eval do
|
14
15
|
attr_accessor :last_login_at_attribute_name, # last login attribute name.
|
15
16
|
:last_logout_at_attribute_name, # last logout attribute name.
|
16
17
|
:last_activity_at_attribute_name, # last activity attribute name.
|
17
18
|
:last_login_from_ip_address_name, # last activity login source
|
18
|
-
:activity_timeout # how long since last activity is
|
19
|
+
:activity_timeout # how long since last activity is
|
19
20
|
#the user defined logged out?
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
base.sorcery_config.instance_eval do
|
23
24
|
@defaults.merge!(:@last_login_at_attribute_name => :last_login_at,
|
24
25
|
:@last_logout_at_attribute_name => :last_logout_at,
|
@@ -28,47 +29,39 @@ module Sorcery
|
|
28
29
|
reset!
|
29
30
|
end
|
30
31
|
|
31
|
-
base.sorcery_config.after_config << :
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
base.sorcery_config.after_config << :define_activity_logging_fields
|
33
|
+
end
|
34
|
+
|
35
|
+
module InstanceMethods
|
36
|
+
def set_last_login_at(time)
|
37
|
+
sorcery_adapter.update_attribute(sorcery_config.last_login_at_attribute_name, time)
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_last_logout_at(time)
|
41
|
+
sorcery_adapter.update_attribute(sorcery_config.last_logout_at_attribute_name, time)
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_last_activity_at(time)
|
45
|
+
sorcery_adapter.update_attribute(sorcery_config.last_activity_at_attribute_name, time)
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_last_ip_addess(ip_address)
|
49
|
+
sorcery_adapter.update_attribute(sorcery_config.last_login_from_ip_address_name, ip_address)
|
38
50
|
end
|
39
51
|
end
|
40
|
-
|
52
|
+
|
41
53
|
module ClassMethods
|
42
54
|
# get all users with last_activity within timeout
|
43
55
|
def current_users
|
44
|
-
|
45
|
-
get_current_users
|
56
|
+
sorcery_adapter.get_current_users
|
46
57
|
end
|
47
58
|
|
48
59
|
protected
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
field sorcery_config.last_login_from_ip_address_name, :type => String
|
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
|
60
|
+
def define_activity_logging_fields
|
61
|
+
sorcery_adapter.define_field sorcery_config.last_login_at_attribute_name, Time
|
62
|
+
sorcery_adapter.define_field sorcery_config.last_logout_at_attribute_name, Time
|
63
|
+
sorcery_adapter.define_field sorcery_config.last_activity_at_attribute_name, Time
|
64
|
+
sorcery_adapter.define_field sorcery_config.last_login_from_ip_address_name, String
|
72
65
|
end
|
73
66
|
end
|
74
67
|
end
|
@@ -35,13 +35,7 @@ module Sorcery
|
|
35
35
|
end
|
36
36
|
|
37
37
|
base.sorcery_config.before_authenticate << :prevent_locked_user_login
|
38
|
-
base.sorcery_config.after_config << :
|
39
|
-
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
40
|
-
base.sorcery_config.after_config << :define_brute_force_protection_mongo_mapper_fields
|
41
|
-
end
|
42
|
-
if defined?(DataMapper) and base.ancestors.include?(DataMapper::Resource)
|
43
|
-
base.sorcery_config.after_config << :define_brute_force_protection_datamapper_fields
|
44
|
-
end
|
38
|
+
base.sorcery_config.after_config << :define_brute_force_protection_fields
|
45
39
|
base.extend(ClassMethods)
|
46
40
|
base.send(:include, InstanceMethods)
|
47
41
|
end
|
@@ -49,35 +43,16 @@ module Sorcery
|
|
49
43
|
module ClassMethods
|
50
44
|
def load_from_unlock_token(token)
|
51
45
|
return nil if token.blank?
|
52
|
-
user =
|
46
|
+
user = sorcery_adapter.find_by_token(sorcery_config.unlock_token_attribute_name,token)
|
53
47
|
user
|
54
48
|
end
|
55
49
|
|
56
50
|
protected
|
57
51
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
def define_brute_force_protection_mongo_mapper_fields
|
65
|
-
key sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0
|
66
|
-
key sorcery_config.lock_expires_at_attribute_name, Time
|
67
|
-
key sorcery_config.unlock_token_attribute_name, String
|
68
|
-
end
|
69
|
-
|
70
|
-
def define_brute_force_protection_datamapper_fields
|
71
|
-
property sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0
|
72
|
-
property sorcery_config.lock_expires_at_attribute_name, Time
|
73
|
-
property sorcery_config.unlock_token_attribute_name, String
|
74
|
-
[sorcery_config.lock_expires_at_attribute_name].each do |sym|
|
75
|
-
alias_method "orig_#{sym}", sym
|
76
|
-
define_method(sym) do
|
77
|
-
t = send("orig_#{sym}")
|
78
|
-
t && Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec, 0)
|
79
|
-
end
|
80
|
-
end
|
52
|
+
def define_brute_force_protection_fields
|
53
|
+
sorcery_adapter.define_field sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0
|
54
|
+
sorcery_adapter.define_field sorcery_config.lock_expires_at_attribute_name, Time
|
55
|
+
sorcery_adapter.define_field sorcery_config.unlock_token_attribute_name, String
|
81
56
|
end
|
82
57
|
end
|
83
58
|
|
@@ -87,9 +62,12 @@ module Sorcery
|
|
87
62
|
def register_failed_login!
|
88
63
|
config = sorcery_config
|
89
64
|
return if !unlocked?
|
90
|
-
|
91
|
-
|
92
|
-
|
65
|
+
|
66
|
+
sorcery_adapter.increment(config.failed_logins_count_attribute_name)
|
67
|
+
|
68
|
+
if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
|
69
|
+
lock!
|
70
|
+
end
|
93
71
|
end
|
94
72
|
|
95
73
|
# /!\
|
@@ -100,7 +78,11 @@ module Sorcery
|
|
100
78
|
attributes = {config.lock_expires_at_attribute_name => nil,
|
101
79
|
config.failed_logins_count_attribute_name => 0,
|
102
80
|
config.unlock_token_attribute_name => nil}
|
103
|
-
|
81
|
+
sorcery_adapter.update_attributes(attributes)
|
82
|
+
end
|
83
|
+
|
84
|
+
def locked?
|
85
|
+
!unlocked?
|
104
86
|
end
|
105
87
|
|
106
88
|
protected
|
@@ -109,7 +91,7 @@ module Sorcery
|
|
109
91
|
config = sorcery_config
|
110
92
|
attributes = {config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period,
|
111
93
|
config.unlock_token_attribute_name => TemporaryToken.generate_random_token}
|
112
|
-
|
94
|
+
sorcery_adapter.update_attributes(attributes)
|
113
95
|
|
114
96
|
unless config.unlock_token_mailer_disabled || config.unlock_token_mailer.nil?
|
115
97
|
send_unlock_token_email!
|
@@ -122,7 +104,9 @@ module Sorcery
|
|
122
104
|
end
|
123
105
|
|
124
106
|
def send_unlock_token_email!
|
125
|
-
|
107
|
+
return if sorcery_config.unlock_token_email_method_name.nil?
|
108
|
+
|
109
|
+
generic_send_email(:unlock_token_email_method_name, :unlock_token_mailer)
|
126
110
|
end
|
127
111
|
|
128
112
|
# Prevents a locked user from logging in, and unlocks users that expired their lock time.
|
@@ -8,7 +8,7 @@ module Sorcery
|
|
8
8
|
# Socery assumes (read: requires) you will create external users in the same table where
|
9
9
|
# you keep your regular users,
|
10
10
|
# 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
|
11
|
+
# and that that separate table has a few rows for each user, facebook and twitter
|
12
12
|
# for example (a one-to-many relationship).
|
13
13
|
#
|
14
14
|
# External users will have a null crypted_password field, since we do not hold their password.
|
@@ -22,7 +22,7 @@ module Sorcery
|
|
22
22
|
:provider_uid_attribute_name
|
23
23
|
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
base.sorcery_config.instance_eval do
|
27
27
|
@defaults.merge!(:@authentications_class => nil,
|
28
28
|
:@authentications_user_id_attribute_name => :user_id,
|
@@ -31,26 +31,70 @@ module Sorcery
|
|
31
31
|
|
32
32
|
reset!
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
base.send(:include, InstanceMethods)
|
36
36
|
base.extend(ClassMethods)
|
37
37
|
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
module ClassMethods
|
41
41
|
# takes a provider and uid and finds a user by them.
|
42
42
|
def load_from_provider(provider,uid)
|
43
43
|
config = sorcery_config
|
44
|
-
authentication = config.authentications_class.
|
45
|
-
user =
|
44
|
+
authentication = config.authentications_class.sorcery_adapter.find_by_oauth_credentials(provider, uid)
|
45
|
+
user = sorcery_adapter.find_by_id(authentication.send(config.authentications_user_id_attribute_name)) if authentication
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_and_validate_from_provider(provider, uid, attrs)
|
49
|
+
user = new(attrs)
|
50
|
+
user.send(sorcery_config.authentications_class.to_s.downcase.pluralize).build(
|
51
|
+
sorcery_config.provider_uid_attribute_name => uid,
|
52
|
+
sorcery_config.provider_attribute_name => provider
|
53
|
+
)
|
54
|
+
saved = user.sorcery_adapter.save
|
55
|
+
[user, saved]
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_from_provider(provider, uid, attrs)
|
59
|
+
user = new
|
60
|
+
attrs.each do |k,v|
|
61
|
+
user.send(:"#{k}=", v)
|
62
|
+
end
|
63
|
+
|
64
|
+
if block_given?
|
65
|
+
return false unless yield user
|
66
|
+
end
|
67
|
+
|
68
|
+
sorcery_adapter.transaction do
|
69
|
+
user.sorcery_adapter.save(:validate => false)
|
70
|
+
sorcery_config.authentications_class.create!(
|
71
|
+
sorcery_config.authentications_user_id_attribute_name => user.id,
|
72
|
+
sorcery_config.provider_attribute_name => provider,
|
73
|
+
sorcery_config.provider_uid_attribute_name => uid
|
74
|
+
)
|
75
|
+
end
|
76
|
+
user
|
46
77
|
end
|
47
78
|
end
|
48
|
-
|
79
|
+
|
49
80
|
module InstanceMethods
|
81
|
+
def add_provider_to_user(provider, uid)
|
82
|
+
authentications = sorcery_config.authentications_class.name.underscore.pluralize
|
83
|
+
# first check to see if user has a particular authentication already
|
84
|
+
if sorcery_adapter.find_authentication_by_oauth_credentials(authentications, provider, uid).nil?
|
85
|
+
user = send(authentications).build(sorcery_config.provider_uid_attribute_name => uid,
|
86
|
+
sorcery_config.provider_attribute_name => provider)
|
87
|
+
user.sorcery_adapter.save(validate: false)
|
88
|
+
else
|
89
|
+
user = false
|
90
|
+
end
|
91
|
+
|
92
|
+
user
|
93
|
+
end
|
50
94
|
|
51
95
|
end
|
52
|
-
|
96
|
+
|
53
97
|
end
|
54
98
|
end
|
55
99
|
end
|
56
|
-
end
|
100
|
+
end
|
@@ -1,7 +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
|
4
|
+
# The Remember Me submodule takes care of setting the user's cookie so that he will
|
5
5
|
# be automatically logged in to the site on every visit,
|
6
6
|
# until the cookie expires.
|
7
7
|
module RememberMe
|
@@ -22,14 +22,7 @@ module Sorcery
|
|
22
22
|
end
|
23
23
|
|
24
24
|
base.send(:include, InstanceMethods)
|
25
|
-
|
26
|
-
base.sorcery_config.after_config << :define_remember_me_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
27
|
-
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
28
|
-
base.sorcery_config.after_config << :define_remember_me_mongo_mapper_fields
|
29
|
-
end
|
30
|
-
if defined?(DataMapper) and base.ancestors.include?(DataMapper::Resource)
|
31
|
-
base.sorcery_config.after_config << :define_remember_me_datamapper_fields
|
32
|
-
end
|
25
|
+
base.sorcery_config.after_config << :define_remember_me_fields
|
33
26
|
|
34
27
|
base.extend(ClassMethods)
|
35
28
|
end
|
@@ -37,41 +30,29 @@ module Sorcery
|
|
37
30
|
module ClassMethods
|
38
31
|
protected
|
39
32
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def define_remember_me_mongo_mapper_fields
|
46
|
-
key sorcery_config.remember_me_token_attribute_name, String
|
47
|
-
key sorcery_config.remember_me_token_expires_at_attribute_name, Time
|
33
|
+
def define_remember_me_fields
|
34
|
+
sorcery_adapter.define_field sorcery_config.remember_me_token_attribute_name, String
|
35
|
+
sorcery_adapter.define_field sorcery_config.remember_me_token_expires_at_attribute_name, Time
|
48
36
|
end
|
49
37
|
|
50
|
-
def define_remember_me_datamapper_fields
|
51
|
-
property sorcery_config.remember_me_token_attribute_name, String
|
52
|
-
property sorcery_config.remember_me_token_expires_at_attribute_name, Time
|
53
|
-
[sorcery_config.remember_me_token_expires_at_attribute_name].each do |sym|
|
54
|
-
alias_method "orig_#{sym}", sym
|
55
|
-
define_method(sym) do
|
56
|
-
t = send("orig_#{sym}")
|
57
|
-
t && Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec, 0)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
38
|
end
|
62
39
|
|
63
40
|
module InstanceMethods
|
64
41
|
# You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
|
65
42
|
def remember_me!
|
66
43
|
config = sorcery_config
|
67
|
-
self.
|
44
|
+
self.sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => TemporaryToken.generate_random_token,
|
68
45
|
config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for)
|
69
46
|
end
|
70
|
-
|
47
|
+
|
48
|
+
def has_remember_me_token?
|
49
|
+
self.send(sorcery_config.remember_me_token_attribute_name).present?
|
50
|
+
end
|
51
|
+
|
71
52
|
# You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method.
|
72
53
|
def forget_me!
|
73
54
|
config = sorcery_config
|
74
|
-
self.
|
55
|
+
self.sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => nil,
|
75
56
|
config.remember_me_token_expires_at_attribute_name => nil)
|
76
57
|
end
|
77
58
|
end
|