sorcery 0.9.1 → 0.10.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.

Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +29 -104
  3. data/CHANGELOG.md +13 -1
  4. data/Gemfile +2 -16
  5. data/README.md +124 -272
  6. data/Rakefile +2 -2
  7. data/gemfiles/{mongoid-rails40.gemfile → active_record-rails42.gemfile} +1 -3
  8. data/lib/generators/sorcery/helpers.rb +4 -4
  9. data/lib/generators/sorcery/install_generator.rb +25 -19
  10. data/lib/generators/sorcery/templates/initializer.rb +27 -52
  11. data/lib/generators/sorcery/templates/migration/activity_logging.rb +2 -2
  12. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +1 -1
  13. data/lib/generators/sorcery/templates/migration/core.rb +3 -3
  14. data/lib/generators/sorcery/templates/migration/external.rb +2 -2
  15. data/lib/generators/sorcery/templates/migration/remember_me.rb +2 -2
  16. data/lib/generators/sorcery/templates/migration/reset_password.rb +2 -2
  17. data/lib/generators/sorcery/templates/migration/user_activation.rb +2 -2
  18. data/lib/sorcery.rb +0 -28
  19. data/lib/sorcery/adapters/active_record_adapter.rb +7 -18
  20. data/lib/sorcery/controller.rb +19 -21
  21. data/lib/sorcery/controller/config.rb +20 -18
  22. data/lib/sorcery/controller/submodules/activity_logging.rb +7 -15
  23. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
  24. data/lib/sorcery/controller/submodules/external.rb +22 -14
  25. data/lib/sorcery/controller/submodules/http_basic_auth.rb +16 -19
  26. data/lib/sorcery/controller/submodules/remember_me.rb +15 -10
  27. data/lib/sorcery/controller/submodules/session_timeout.rb +7 -8
  28. data/lib/sorcery/crypto_providers/aes256.rb +15 -15
  29. data/lib/sorcery/crypto_providers/bcrypt.rb +19 -21
  30. data/lib/sorcery/crypto_providers/common.rb +1 -1
  31. data/lib/sorcery/crypto_providers/md5.rb +5 -5
  32. data/lib/sorcery/crypto_providers/sha1.rb +5 -5
  33. data/lib/sorcery/crypto_providers/sha256.rb +2 -2
  34. data/lib/sorcery/crypto_providers/sha512.rb +3 -3
  35. data/lib/sorcery/engine.rb +3 -8
  36. data/lib/sorcery/model.rb +24 -32
  37. data/lib/sorcery/model/config.rb +64 -49
  38. data/lib/sorcery/model/submodules/activity_logging.rb +31 -12
  39. data/lib/sorcery/model/submodules/brute_force_protection.rb +23 -23
  40. data/lib/sorcery/model/submodules/external.rb +3 -7
  41. data/lib/sorcery/model/submodules/remember_me.rb +19 -7
  42. data/lib/sorcery/model/submodules/reset_password.rb +32 -36
  43. data/lib/sorcery/model/submodules/user_activation.rb +38 -50
  44. data/lib/sorcery/model/temporary_token.rb +2 -2
  45. data/lib/sorcery/protocols/oauth.rb +3 -9
  46. data/lib/sorcery/protocols/oauth2.rb +0 -2
  47. data/lib/sorcery/providers/base.rb +4 -4
  48. data/lib/sorcery/providers/facebook.rb +5 -8
  49. data/lib/sorcery/providers/github.rb +5 -7
  50. data/lib/sorcery/providers/google.rb +3 -5
  51. data/lib/sorcery/providers/heroku.rb +6 -8
  52. data/lib/sorcery/providers/jira.rb +12 -17
  53. data/lib/sorcery/providers/linkedin.rb +6 -8
  54. data/lib/sorcery/providers/liveid.rb +4 -7
  55. data/lib/sorcery/providers/paypal.rb +60 -0
  56. data/lib/sorcery/providers/salesforce.rb +3 -5
  57. data/lib/sorcery/providers/slack.rb +45 -0
  58. data/lib/sorcery/providers/twitter.rb +4 -6
  59. data/lib/sorcery/providers/vk.rb +3 -5
  60. data/lib/sorcery/providers/wechat.rb +79 -0
  61. data/lib/sorcery/providers/xing.rb +7 -10
  62. data/lib/sorcery/test_helpers/internal.rb +10 -10
  63. data/lib/sorcery/test_helpers/internal/rails.rb +16 -8
  64. data/lib/sorcery/test_helpers/rails/controller.rb +1 -1
  65. data/lib/sorcery/test_helpers/rails/integration.rb +5 -6
  66. data/lib/sorcery/version.rb +1 -1
  67. data/sorcery.gemspec +25 -27
  68. data/spec/active_record/user_activation_spec.rb +2 -3
  69. data/spec/active_record/user_activity_logging_spec.rb +2 -4
  70. data/spec/active_record/user_brute_force_protection_spec.rb +3 -4
  71. data/spec/active_record/user_oauth_spec.rb +3 -4
  72. data/spec/active_record/user_remember_me_spec.rb +3 -4
  73. data/spec/active_record/user_reset_password_spec.rb +2 -3
  74. data/spec/active_record/user_spec.rb +7 -7
  75. data/spec/controllers/controller_activity_logging_spec.rb +13 -24
  76. data/spec/controllers/controller_brute_force_protection_spec.rb +6 -8
  77. data/spec/controllers/controller_http_basic_auth_spec.rb +19 -20
  78. data/spec/controllers/controller_oauth2_spec.rb +125 -100
  79. data/spec/controllers/controller_oauth_spec.rb +86 -66
  80. data/spec/controllers/controller_remember_me_spec.rb +35 -30
  81. data/spec/controllers/controller_session_timeout_spec.rb +14 -15
  82. data/spec/controllers/controller_spec.rb +77 -111
  83. data/spec/orm/active_record.rb +1 -1
  84. data/spec/rails_app/app/active_record/authentication.rb +1 -1
  85. data/spec/rails_app/app/active_record/user.rb +2 -2
  86. data/spec/rails_app/app/controllers/sorcery_controller.rb +89 -24
  87. data/spec/rails_app/app/mailers/sorcery_mailer.rb +16 -17
  88. data/spec/rails_app/config.ru +1 -1
  89. data/spec/rails_app/config/application.rb +7 -7
  90. data/spec/rails_app/config/boot.rb +1 -1
  91. data/spec/rails_app/config/environments/test.rb +1 -1
  92. data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +11 -0
  93. data/spec/rails_app/config/initializers/session_store.rb +3 -3
  94. data/spec/rails_app/config/routes.rb +11 -1
  95. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +4 -4
  96. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +8 -8
  97. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +5 -5
  98. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +5 -5
  99. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +3 -3
  100. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +6 -6
  101. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +5 -5
  102. data/spec/shared_examples/user_activation_shared_examples.rb +99 -58
  103. data/spec/shared_examples/user_activity_logging_shared_examples.rb +47 -41
  104. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +19 -24
  105. data/spec/shared_examples/user_oauth_shared_examples.rb +7 -10
  106. data/spec/shared_examples/user_remember_me_shared_examples.rb +90 -21
  107. data/spec/shared_examples/user_reset_password_shared_examples.rb +52 -54
  108. data/spec/shared_examples/user_shared_examples.rb +215 -118
  109. data/spec/sorcery_crypto_providers_spec.rb +63 -76
  110. data/spec/spec_helper.rb +17 -13
  111. metadata +28 -83
  112. data/gemfiles/mongo_mapper-rails40.gemfile +0 -9
  113. data/gemfiles/mongo_mapper-rails41.gemfile +0 -9
  114. data/gemfiles/mongoid-rails41.gemfile +0 -9
  115. data/gemfiles/mongoid3-rails32.gemfile +0 -9
  116. data/lib/sorcery/adapters/data_mapper_adapter.rb +0 -176
  117. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +0 -110
  118. data/lib/sorcery/adapters/mongoid_adapter.rb +0 -97
  119. data/lib/sorcery/railties/tasks.rake +0 -6
  120. data/spec/data_mapper/user_activation_spec.rb +0 -10
  121. data/spec/data_mapper/user_activity_logging_spec.rb +0 -14
  122. data/spec/data_mapper/user_brute_force_protection_spec.rb +0 -9
  123. data/spec/data_mapper/user_oauth_spec.rb +0 -9
  124. data/spec/data_mapper/user_remember_me_spec.rb +0 -8
  125. data/spec/data_mapper/user_reset_password_spec.rb +0 -8
  126. data/spec/data_mapper/user_spec.rb +0 -27
  127. data/spec/mongo_mapper/user_activation_spec.rb +0 -9
  128. data/spec/mongo_mapper/user_activity_logging_spec.rb +0 -8
  129. data/spec/mongo_mapper/user_brute_force_protection_spec.rb +0 -8
  130. data/spec/mongo_mapper/user_oauth_spec.rb +0 -8
  131. data/spec/mongo_mapper/user_remember_me_spec.rb +0 -8
  132. data/spec/mongo_mapper/user_reset_password_spec.rb +0 -8
  133. data/spec/mongo_mapper/user_spec.rb +0 -37
  134. data/spec/mongoid/user_activation_spec.rb +0 -9
  135. data/spec/mongoid/user_activity_logging_spec.rb +0 -8
  136. data/spec/mongoid/user_brute_force_protection_spec.rb +0 -8
  137. data/spec/mongoid/user_oauth_spec.rb +0 -8
  138. data/spec/mongoid/user_remember_me_spec.rb +0 -8
  139. data/spec/mongoid/user_reset_password_spec.rb +0 -8
  140. data/spec/mongoid/user_spec.rb +0 -51
  141. data/spec/orm/data_mapper.rb +0 -48
  142. data/spec/orm/mongo_mapper.rb +0 -10
  143. data/spec/orm/mongoid.rb +0 -22
  144. data/spec/rails_app/app/data_mapper/authentication.rb +0 -8
  145. data/spec/rails_app/app/data_mapper/user.rb +0 -7
  146. data/spec/rails_app/app/mongo_mapper/authentication.rb +0 -6
  147. data/spec/rails_app/app/mongo_mapper/user.rb +0 -7
  148. data/spec/rails_app/app/mongoid/authentication.rb +0 -7
  149. data/spec/rails_app/app/mongoid/user.rb +0 -7
@@ -4,43 +4,49 @@
4
4
  module Sorcery
5
5
  module Model
6
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.
7
+ # change default username attribute, for example, to use :email as the login.
8
+ attr_accessor :username_attribute_names
9
+ # change *virtual* password attribute, the one which is used until an encrypted one is generated.
10
+ attr_accessor :password_attribute_name
11
+ # change default email attribute.
12
+ attr_accessor :email_attribute_name
13
+ # downcase the username before trying to authenticate, default is false
14
+ attr_accessor :downcase_username_before_authenticating
15
+ # change default crypted_password attribute.
16
+ attr_accessor :crypted_password_attribute_name
17
+ # what pattern to use to join the password with the salt
18
+ attr_accessor :salt_join_token
19
+ # change default salt attribute.
20
+ attr_accessor :salt_attribute_name
21
+ # how many times to apply encryption to the password.
22
+ attr_accessor :stretches
23
+ # encryption key used to encrypt reversible encryptions such as AES256.
24
+ attr_accessor :encryption_key
25
+ # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
26
+ attr_accessor :subclasses_inherit_config
27
+ # configured in config/application.rb
28
+ attr_accessor :submodules
29
+ # an array of method names to call before authentication completes. used internally.
30
+ attr_accessor :before_authenticate
31
+ # method to send email related
32
+ # options: `:deliver_later`, `:deliver_now`, `:deliver`
33
+ # Default: :deliver (Rails version < 4.2) or :deliver_now (Rails version 4.2+)
34
+ # method to send email related
35
+ attr_accessor :email_delivery_method
36
+ # an array of method names to call after configuration by user. used internally.
37
+ attr_accessor :after_config
38
+
39
+ # change default encryption_provider.
40
+ attr_reader :encryption_provider
41
+ # use an external encryption class.
42
+ attr_reader :custom_encryption_provider
43
+ # encryption algorithm name. See 'encryption_algorithm=' below for available options.
44
+ attr_reader :encryption_algorithm
39
45
 
40
46
  def initialize
41
47
  @defaults = {
42
48
  :@submodules => [],
43
- :@username_attribute_names => [:email],
49
+ :@username_attribute_names => [:email],
44
50
  :@password_attribute_name => :password,
45
51
  :@downcase_username_before_authenticating => false,
46
52
  :@email_attribute_name => :email,
@@ -49,25 +55,26 @@ module Sorcery
49
55
  :@encryption_provider => CryptoProviders::BCrypt,
50
56
  :@custom_encryption_provider => nil,
51
57
  :@encryption_key => nil,
52
- :@salt_join_token => "",
58
+ :@salt_join_token => '',
53
59
  :@salt_attribute_name => :salt,
54
60
  :@stretches => nil,
55
61
  :@subclasses_inherit_config => false,
56
62
  :@before_authenticate => [],
57
- :@after_config => []
63
+ :@after_config => [],
64
+ :@email_delivery_method => default_email_delivery_method
58
65
  }
59
66
  reset!
60
67
  end
61
68
 
62
69
  # Resets all configuration options to their default values.
63
70
  def reset!
64
- @defaults.each do |k,v|
65
- instance_variable_set(k,v)
71
+ @defaults.each do |k, v|
72
+ instance_variable_set(k, v)
66
73
  end
67
74
  end
68
75
 
69
76
  def username_attribute_names=(fields)
70
- @username_attribute_names = fields.kind_of?(Array) ? fields : [fields]
77
+ @username_attribute_names = fields.is_a?(Array) ? fields : [fields]
71
78
  end
72
79
 
73
80
  def custom_encryption_provider=(provider)
@@ -77,20 +84,28 @@ module Sorcery
77
84
  def encryption_algorithm=(algo)
78
85
  @encryption_algorithm = algo
79
86
  @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")
87
+ when :none then nil
88
+ when :md5 then CryptoProviders::MD5
89
+ when :sha1 then CryptoProviders::SHA1
90
+ when :sha256 then CryptoProviders::SHA256
91
+ when :sha512 then CryptoProviders::SHA512
92
+ when :aes256 then CryptoProviders::AES256
93
+ when :bcrypt then CryptoProviders::BCrypt
94
+ when :custom then @custom_encryption_provider
95
+ else raise ArgumentError, "Encryption algorithm supplied, #{algo}, is invalid"
89
96
  end
90
97
  end
91
98
 
92
- end
99
+ private
100
+
101
+ def default_email_delivery_method
102
+ # Rails 4.2 deprecates #deliver
103
+ rails_version_bigger_than_or_equal?('4.2.0') ? :deliver_now : :deliver
104
+ end
93
105
 
106
+ def rails_version_bigger_than_or_equal?(version)
107
+ Gem::Version.new(version) <= Gem::Version.new(Rails.version)
108
+ end
109
+ end
94
110
  end
95
111
  end
96
-
@@ -12,12 +12,16 @@ module Sorcery
12
12
  base.send(:include, InstanceMethods)
13
13
 
14
14
  base.sorcery_config.class_eval do
15
- attr_accessor :last_login_at_attribute_name, # last login attribute name.
16
- :last_logout_at_attribute_name, # last logout attribute name.
17
- :last_activity_at_attribute_name, # last activity attribute name.
18
- :last_login_from_ip_address_name, # last activity login source
19
- :activity_timeout # how long since last activity is
20
- #the user defined logged out?
15
+ # last login attribute name.
16
+ attr_accessor :last_login_at_attribute_name
17
+ # last logout attribute name.
18
+ attr_accessor :last_logout_at_attribute_name
19
+ # last activity attribute name.
20
+ attr_accessor :last_activity_at_attribute_name
21
+ # last activity login source
22
+ attr_accessor :last_login_from_ip_address_name
23
+ # how long since last activity is the user defined offline
24
+ attr_accessor :activity_timeout
21
25
  end
22
26
 
23
27
  base.sorcery_config.instance_eval do
@@ -45,18 +49,33 @@ module Sorcery
45
49
  sorcery_adapter.update_attribute(sorcery_config.last_activity_at_attribute_name, time)
46
50
  end
47
51
 
48
- def set_last_ip_addess(ip_address)
52
+ def set_last_ip_address(ip_address)
49
53
  sorcery_adapter.update_attribute(sorcery_config.last_login_from_ip_address_name, ip_address)
50
54
  end
51
- end
52
55
 
53
- module ClassMethods
54
- # get all users with last_activity within timeout
55
- def current_users
56
- sorcery_adapter.get_current_users
56
+ # online method shows if user is active (logout action makes user inactive too)
57
+ def online?
58
+ return false if send(sorcery_config.last_activity_at_attribute_name).nil?
59
+
60
+ logged_in? && send(sorcery_config.last_activity_at_attribute_name) > sorcery_config.activity_timeout.seconds.ago
61
+ end
62
+
63
+ # shows if user is logged in, but it not show if user is online - see online?
64
+ def logged_in?
65
+ return false if send(sorcery_config.last_login_at_attribute_name).nil?
66
+ return true if send(sorcery_config.last_login_at_attribute_name).present? && send(sorcery_config.last_logout_at_attribute_name).nil?
67
+
68
+ send(sorcery_config.last_login_at_attribute_name) > send(sorcery_config.last_logout_at_attribute_name)
57
69
  end
58
70
 
71
+ def logged_out?
72
+ !logged_in?
73
+ end
74
+ end
75
+
76
+ module ClassMethods
59
77
  protected
78
+
60
79
  def define_activity_logging_fields
61
80
  sorcery_adapter.define_field sorcery_config.last_login_at_attribute_name, Time
62
81
  sorcery_adapter.define_field sorcery_config.last_logout_at_attribute_name, Time
@@ -10,15 +10,15 @@ module Sorcery
10
10
  base.sorcery_config.class_eval do
11
11
  attr_accessor :failed_logins_count_attribute_name, # failed logins attribute name.
12
12
  :lock_expires_at_attribute_name, # this field indicates whether user
13
- # is banned and when it will be active again.
13
+ # is banned and when it will be active again.
14
14
  :consecutive_login_retries_amount_limit, # how many failed logins allowed.
15
15
  :login_lock_time_period, # how long the user should be banned.
16
- # in seconds. 0 for permanent.
16
+ # in seconds. 0 for permanent.
17
17
 
18
18
  :unlock_token_attribute_name, # Unlock token attribute name
19
19
  :unlock_token_email_method_name, # Mailer method name
20
20
  :unlock_token_mailer_disabled, # When true, dont send unlock token via email
21
- :unlock_token_mailer # Mailer class
21
+ :unlock_token_mailer # Mailer class
22
22
  end
23
23
 
24
24
  base.sorcery_config.instance_eval do
@@ -43,14 +43,14 @@ module Sorcery
43
43
  module ClassMethods
44
44
  def load_from_unlock_token(token)
45
45
  return nil if token.blank?
46
- user = sorcery_adapter.find_by_token(sorcery_config.unlock_token_attribute_name,token)
46
+ user = sorcery_adapter.find_by_token(sorcery_config.unlock_token_attribute_name, token)
47
47
  user
48
48
  end
49
49
 
50
50
  protected
51
51
 
52
52
  def define_brute_force_protection_fields
53
- sorcery_adapter.define_field sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0
53
+ sorcery_adapter.define_field sorcery_config.failed_logins_count_attribute_name, Integer, default: 0
54
54
  sorcery_adapter.define_field sorcery_config.lock_expires_at_attribute_name, Time
55
55
  sorcery_adapter.define_field sorcery_config.unlock_token_attribute_name, String
56
56
  end
@@ -58,39 +58,39 @@ module Sorcery
58
58
 
59
59
  module InstanceMethods
60
60
  # Called by the controller to increment the failed logins counter.
61
- # Calls 'lock!' if login retries limit was reached.
61
+ # Calls 'login_lock!' if login retries limit was reached.
62
62
  def register_failed_login!
63
63
  config = sorcery_config
64
- return if !unlocked?
64
+ return unless login_unlocked?
65
65
 
66
66
  sorcery_adapter.increment(config.failed_logins_count_attribute_name)
67
67
 
68
- if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
69
- lock!
68
+ if send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
69
+ login_lock!
70
70
  end
71
71
  end
72
72
 
73
73
  # /!\
74
74
  # Moved out of protected for use like activate! in controller
75
75
  # /!\
76
- def unlock!
76
+ def login_unlock!
77
77
  config = sorcery_config
78
- attributes = {config.lock_expires_at_attribute_name => nil,
79
- config.failed_logins_count_attribute_name => 0,
80
- config.unlock_token_attribute_name => nil}
78
+ attributes = { config.lock_expires_at_attribute_name => nil,
79
+ config.failed_logins_count_attribute_name => 0,
80
+ config.unlock_token_attribute_name => nil }
81
81
  sorcery_adapter.update_attributes(attributes)
82
82
  end
83
83
 
84
- def locked?
85
- !unlocked?
84
+ def login_locked?
85
+ !login_unlocked?
86
86
  end
87
87
 
88
88
  protected
89
89
 
90
- def lock!
90
+ def login_lock!
91
91
  config = sorcery_config
92
- attributes = {config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period,
93
- config.unlock_token_attribute_name => TemporaryToken.generate_random_token}
92
+ attributes = { config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period,
93
+ config.unlock_token_attribute_name => TemporaryToken.generate_random_token }
94
94
  sorcery_adapter.update_attributes(attributes)
95
95
 
96
96
  unless config.unlock_token_mailer_disabled || config.unlock_token_mailer.nil?
@@ -98,9 +98,9 @@ module Sorcery
98
98
  end
99
99
  end
100
100
 
101
- def unlocked?
101
+ def login_unlocked?
102
102
  config = sorcery_config
103
- self.send(config.lock_expires_at_attribute_name).nil?
103
+ send(config.lock_expires_at_attribute_name).nil?
104
104
  end
105
105
 
106
106
  def send_unlock_token_email!
@@ -113,10 +113,10 @@ module Sorcery
113
113
  # Runs as a hook before authenticate.
114
114
  def prevent_locked_user_login
115
115
  config = sorcery_config
116
- if !self.unlocked? && config.login_lock_time_period != 0
117
- self.unlock! if self.send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone
116
+ if !login_unlocked? && config.login_lock_time_period != 0
117
+ login_unlock! if send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone
118
118
  end
119
- unlocked?
119
+ login_unlocked?
120
120
  end
121
121
  end
122
122
  end
@@ -20,7 +20,6 @@ module Sorcery
20
20
  :authentications_user_id_attribute_name,
21
21
  :provider_attribute_name,
22
22
  :provider_uid_attribute_name
23
-
24
23
  end
25
24
 
26
25
  base.sorcery_config.instance_eval do
@@ -34,12 +33,11 @@ module Sorcery
34
33
 
35
34
  base.send(:include, InstanceMethods)
36
35
  base.extend(ClassMethods)
37
-
38
36
  end
39
37
 
40
38
  module ClassMethods
41
39
  # takes a provider and uid and finds a user by them.
42
- def load_from_provider(provider,uid)
40
+ def load_from_provider(provider, uid)
43
41
  config = sorcery_config
44
42
  authentication = config.authentications_class.sorcery_adapter.find_by_oauth_credentials(provider, uid)
45
43
  user = sorcery_adapter.find_by_id(authentication.send(config.authentications_user_id_attribute_name)) if authentication
@@ -57,7 +55,7 @@ module Sorcery
57
55
 
58
56
  def create_from_provider(provider, uid, attrs)
59
57
  user = new
60
- attrs.each do |k,v|
58
+ attrs.each do |k, v|
61
59
  user.send(:"#{k}=", v)
62
60
  end
63
61
 
@@ -66,7 +64,7 @@ module Sorcery
66
64
  end
67
65
 
68
66
  sorcery_adapter.transaction do
69
- user.sorcery_adapter.save(:validate => false)
67
+ user.sorcery_adapter.save(validate: false)
70
68
  sorcery_config.authentications_class.create!(
71
69
  sorcery_config.authentications_user_id_attribute_name => user.id,
72
70
  sorcery_config.provider_attribute_name => provider,
@@ -91,9 +89,7 @@ module Sorcery
91
89
 
92
90
  user
93
91
  end
94
-
95
92
  end
96
-
97
93
  end
98
94
  end
99
95
  end
@@ -9,13 +9,14 @@ module Sorcery
9
9
  base.sorcery_config.class_eval do
10
10
  attr_accessor :remember_me_token_attribute_name, # the attribute in the model class.
11
11
  :remember_me_token_expires_at_attribute_name, # the expires attribute in the model class.
12
+ :remember_me_token_persist_globally, # persist a single token globally for all logins/logouts (supporting multiple simultaneous browsers)
12
13
  :remember_me_for # how long in seconds to remember.
13
-
14
14
  end
15
15
 
16
16
  base.sorcery_config.instance_eval do
17
17
  @defaults.merge!(:@remember_me_token_attribute_name => :remember_me_token,
18
18
  :@remember_me_token_expires_at_attribute_name => :remember_me_token_expires_at,
19
+ :@remember_me_token_persist_globally => false,
19
20
  :@remember_me_for => 7 * 60 * 60 * 24)
20
21
 
21
22
  reset!
@@ -34,26 +35,37 @@ module Sorcery
34
35
  sorcery_adapter.define_field sorcery_config.remember_me_token_attribute_name, String
35
36
  sorcery_adapter.define_field sorcery_config.remember_me_token_expires_at_attribute_name, Time
36
37
  end
37
-
38
38
  end
39
39
 
40
40
  module InstanceMethods
41
41
  # You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
42
42
  def remember_me!
43
43
  config = sorcery_config
44
- self.sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => TemporaryToken.generate_random_token,
45
- config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for)
44
+
45
+ update_options = { config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for }
46
+
47
+ unless config.remember_me_token_persist_globally && has_remember_me_token?
48
+ update_options[config.remember_me_token_attribute_name] = TemporaryToken.generate_random_token
49
+ end
50
+
51
+ sorcery_adapter.update_attributes(update_options)
46
52
  end
47
53
 
48
54
  def has_remember_me_token?
49
- self.send(sorcery_config.remember_me_token_attribute_name).present?
55
+ send(sorcery_config.remember_me_token_attribute_name).present?
50
56
  end
51
57
 
52
58
  # You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method.
59
+ # We only clear the token value if remember_me_token_persist_globally = true.
53
60
  def forget_me!
61
+ sorcery_config.remember_me_token_persist_globally || force_forget_me!
62
+ end
63
+
64
+ # You shouldn't really use this one yourself - it's called by the controller's 'force_forget_me!' method.
65
+ def force_forget_me!
54
66
  config = sorcery_config
55
- self.sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => nil,
56
- config.remember_me_token_expires_at_attribute_name => nil)
67
+ sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => nil,
68
+ config.remember_me_token_expires_at_attribute_name => nil)
57
69
  end
58
70
  end
59
71
  end
@@ -12,26 +12,23 @@ module Sorcery
12
12
  module ResetPassword
13
13
  def self.included(base)
14
14
  base.sorcery_config.class_eval do
15
- attr_accessor :reset_password_token_attribute_name, # reset password code attribute name.
16
- :reset_password_token_expires_at_attribute_name, # expires at attribute name.
17
- :reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering
18
- # protection.
19
-
20
- :reset_password_mailer, # mailer class. Needed.
21
-
22
- :reset_password_mailer_disabled, # when true sorcery will not automatically
23
- # email password reset details and allow you to
24
- # manually handle how and when email is sent
25
-
26
- :reset_password_email_method_name, # reset password email method on your
27
- # mailer class.
28
-
29
- :reset_password_expiration_period, # how many seconds before the reset request
30
- # expires. nil for never expires.
31
-
32
- :reset_password_time_between_emails # hammering protection, how long to wait
33
- # before allowing another email to be sent.
34
-
15
+ # Reset password code attribute name.
16
+ attr_accessor :reset_password_token_attribute_name
17
+ # Expires at attribute name.
18
+ attr_accessor :reset_password_token_expires_at_attribute_name
19
+ # When was email sent, used for hammering protection.
20
+ attr_accessor :reset_password_email_sent_at_attribute_name
21
+ # Mailer class (needed)
22
+ attr_accessor :reset_password_mailer
23
+ # When true sorcery will not automatically email password reset details and allow you to
24
+ # manually handle how and when email is sent
25
+ attr_accessor :reset_password_mailer_disabled
26
+ # Reset password email method on your mailer class.
27
+ attr_accessor :reset_password_email_method_name
28
+ # How many seconds before the reset request expires. nil for never expires.
29
+ attr_accessor :reset_password_expiration_period
30
+ # Hammering protection, how long to wait before allowing another email to be sent.
31
+ attr_accessor :reset_password_time_between_emails
35
32
  end
36
33
 
37
34
  base.sorcery_config.instance_eval do
@@ -42,7 +39,7 @@ module Sorcery
42
39
  :@reset_password_mailer_disabled => false,
43
40
  :@reset_password_email_method_name => :reset_password_email,
44
41
  :@reset_password_expiration_period => nil,
45
- :@reset_password_time_between_emails => 5 * 60 )
42
+ :@reset_password_time_between_emails => 5 * 60)
46
43
 
47
44
  reset!
48
45
  end
@@ -53,7 +50,6 @@ module Sorcery
53
50
  base.sorcery_config.after_config << :define_reset_password_fields
54
51
 
55
52
  base.send(:include, InstanceMethods)
56
-
57
53
  end
58
54
 
59
55
  module ClassMethods
@@ -70,8 +66,8 @@ module Sorcery
70
66
  # This submodule requires the developer to define his own mailer class to be used by it
71
67
  # when reset_password_mailer_disabled is false
72
68
  def validate_mailer_defined
73
- msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)."
74
- raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil and @sorcery_config.reset_password_mailer_disabled == false
69
+ message = 'To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass).'
70
+ raise ArgumentError, message if @sorcery_config.reset_password_mailer.nil? && @sorcery_config.reset_password_mailer_disabled == false
75
71
  end
76
72
 
77
73
  def define_reset_password_fields
@@ -79,35 +75,36 @@ module Sorcery
79
75
  sorcery_adapter.define_field sorcery_config.reset_password_token_expires_at_attribute_name, Time
80
76
  sorcery_adapter.define_field sorcery_config.reset_password_email_sent_at_attribute_name, Time
81
77
  end
82
-
83
78
  end
84
79
 
85
80
  module InstanceMethods
86
- # generates a reset code with expiration
81
+ # Generates a reset code with expiration
87
82
  def generate_reset_password_token!
88
83
  config = sorcery_config
89
- attributes = {config.reset_password_token_attribute_name => TemporaryToken.generate_random_token,
90
- config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone}
84
+ attributes = { config.reset_password_token_attribute_name => TemporaryToken.generate_random_token,
85
+ config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone }
91
86
  attributes[config.reset_password_token_expires_at_attribute_name] = Time.now.in_time_zone + config.reset_password_expiration_period if config.reset_password_expiration_period
92
87
 
93
- self.sorcery_adapter.update_attributes(attributes)
88
+ sorcery_adapter.update_attributes(attributes)
94
89
  end
95
90
 
96
- # generates a reset code with expiration and sends an email to the user.
91
+ # Generates a reset code with expiration and sends an email to the user.
97
92
  def deliver_reset_password_instructions!
93
+ mail = false
98
94
  config = sorcery_config
99
95
  # hammering protection
100
- return false if config.reset_password_time_between_emails.present? && self.send(config.reset_password_email_sent_at_attribute_name) && self.send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.seconds.ago.utc
96
+ return false if config.reset_password_time_between_emails.present? && send(config.reset_password_email_sent_at_attribute_name) && send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.seconds.ago.utc
101
97
  self.class.sorcery_adapter.transaction do
102
98
  generate_reset_password_token!
103
- send_reset_password_email! unless config.reset_password_mailer_disabled
99
+ mail = send_reset_password_email! unless config.reset_password_mailer_disabled
104
100
  end
101
+ mail
105
102
  end
106
103
 
107
104
  # Clears token and tries to update the new password for the user.
108
105
  def change_password!(new_password)
109
106
  clear_reset_password_token
110
- self.send(:"#{sorcery_config.password_attribute_name}=", new_password)
107
+ send(:"#{sorcery_config.password_attribute_name}=", new_password)
111
108
  sorcery_adapter.save
112
109
  end
113
110
 
@@ -120,11 +117,10 @@ module Sorcery
120
117
  # Clears the token.
121
118
  def clear_reset_password_token
122
119
  config = sorcery_config
123
- self.send(:"#{config.reset_password_token_attribute_name}=", nil)
124
- self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period
120
+ send(:"#{config.reset_password_token_attribute_name}=", nil)
121
+ send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period
125
122
  end
126
123
  end
127
-
128
124
  end
129
125
  end
130
126
  end