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.

Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +75 -14
  4. data/CHANGELOG.md +23 -1
  5. data/Gemfile +1 -0
  6. data/README.md +137 -86
  7. data/gemfiles/active_record-rails40.gemfile +7 -0
  8. data/gemfiles/active_record-rails41.gemfile +3 -2
  9. data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
  10. data/gemfiles/mongo_mapper-rails41.gemfile +2 -1
  11. data/gemfiles/mongoid-rails40.gemfile +9 -0
  12. data/gemfiles/mongoid-rails41.gemfile +3 -5
  13. data/gemfiles/mongoid3-rails32.gemfile +9 -0
  14. data/lib/generators/sorcery/USAGE +1 -1
  15. data/lib/generators/sorcery/install_generator.rb +19 -5
  16. data/lib/generators/sorcery/templates/initializer.rb +34 -9
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +3 -1
  18. data/lib/generators/sorcery/templates/migration/core.rb +2 -2
  19. data/lib/generators/sorcery/templates/migration/external.rb +3 -1
  20. data/lib/sorcery.rb +75 -43
  21. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  22. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  23. data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
  24. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
  25. data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
  26. data/lib/sorcery/controller.rb +5 -64
  27. data/lib/sorcery/controller/config.rb +65 -0
  28. data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
  29. data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
  30. data/lib/sorcery/controller/submodules/external.rb +8 -28
  31. data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
  32. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
  33. data/lib/sorcery/model.rb +43 -175
  34. data/lib/sorcery/model/config.rb +96 -0
  35. data/lib/sorcery/model/submodules/activity_logging.rb +29 -36
  36. data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -37
  37. data/lib/sorcery/model/submodules/external.rb +53 -9
  38. data/lib/sorcery/model/submodules/remember_me.rb +12 -31
  39. data/lib/sorcery/model/submodules/reset_password.rb +21 -39
  40. data/lib/sorcery/model/submodules/user_activation.rb +21 -63
  41. data/lib/sorcery/model/temporary_token.rb +4 -4
  42. data/lib/sorcery/providers/base.rb +11 -0
  43. data/lib/sorcery/providers/facebook.rb +1 -1
  44. data/lib/sorcery/providers/github.rb +1 -1
  45. data/lib/sorcery/providers/google.rb +1 -1
  46. data/lib/sorcery/providers/heroku.rb +57 -0
  47. data/lib/sorcery/providers/jira.rb +77 -0
  48. data/lib/sorcery/providers/linkedin.rb +1 -1
  49. data/lib/sorcery/providers/liveid.rb +1 -1
  50. data/lib/sorcery/providers/salesforce.rb +50 -0
  51. data/lib/sorcery/providers/twitter.rb +1 -1
  52. data/lib/sorcery/providers/vk.rb +6 -4
  53. data/lib/sorcery/providers/xing.rb +1 -1
  54. data/lib/sorcery/test_helpers/internal.rb +7 -3
  55. data/lib/sorcery/test_helpers/rails/controller.rb +5 -1
  56. data/lib/sorcery/version.rb +3 -0
  57. data/sorcery.gemspec +6 -2
  58. data/spec/active_record/user_activity_logging_spec.rb +9 -0
  59. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  60. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  61. data/spec/{active_record → controllers}/controller_http_basic_auth_spec.rb +14 -11
  62. data/spec/{active_record → controllers}/controller_oauth2_spec.rb +128 -56
  63. data/spec/{active_record → controllers}/controller_oauth_spec.rb +94 -70
  64. data/spec/{active_record → controllers}/controller_remember_me_spec.rb +32 -12
  65. data/spec/{active_record → controllers}/controller_session_timeout_spec.rb +15 -5
  66. data/spec/{shared_examples/controller_shared_examples.rb → controllers/controller_spec.rb} +34 -19
  67. data/spec/{datamapper → data_mapper}/user_activation_spec.rb +1 -1
  68. data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
  69. data/spec/{datamapper → data_mapper}/user_brute_force_protection_spec.rb +1 -1
  70. data/spec/{datamapper → data_mapper}/user_oauth_spec.rb +1 -1
  71. data/spec/{datamapper → data_mapper}/user_remember_me_spec.rb +1 -1
  72. data/spec/{datamapper → data_mapper}/user_reset_password_spec.rb +1 -1
  73. data/spec/{datamapper → data_mapper}/user_spec.rb +1 -1
  74. data/spec/mongoid/user_spec.rb +13 -0
  75. data/spec/orm/active_record.rb +12 -0
  76. data/spec/orm/{datamapper.rb → data_mapper.rb} +16 -2
  77. data/spec/orm/mongo_mapper.rb +0 -1
  78. data/spec/orm/mongoid.rb +4 -0
  79. data/spec/rails_app/app/controllers/sorcery_controller.rb +62 -1
  80. data/spec/rails_app/app/{datamapper → data_mapper}/authentication.rb +0 -0
  81. data/spec/rails_app/app/{datamapper → data_mapper}/user.rb +0 -0
  82. data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
  83. data/spec/rails_app/config/routes.rb +9 -0
  84. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
  85. data/spec/shared_examples/user_activation_shared_examples.rb +7 -7
  86. data/spec/shared_examples/user_activity_logging_shared_examples.rb +73 -5
  87. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +127 -9
  88. data/spec/shared_examples/user_oauth_shared_examples.rb +3 -6
  89. data/spec/shared_examples/user_remember_me_shared_examples.rb +6 -3
  90. data/spec/shared_examples/user_reset_password_shared_examples.rb +10 -10
  91. data/spec/shared_examples/user_shared_examples.rb +117 -30
  92. data/spec/spec_helper.rb +7 -22
  93. metadata +36 -58
  94. data/Gemfile.rails4 +0 -22
  95. data/VERSION +0 -1
  96. data/lib/sorcery/model/adapters/active_record.rb +0 -54
  97. data/lib/sorcery/model/adapters/datamapper.rb +0 -123
  98. data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -60
  99. data/lib/sorcery/model/adapters/mongoid.rb +0 -88
  100. data/lib/sorcery/test_helpers/rails.rb +0 -7
  101. data/spec/active_record/controller_activity_logging_spec.rb +0 -29
  102. data/spec/active_record/controller_brute_force_protection_spec.rb +0 -158
  103. data/spec/active_record/controller_spec.rb +0 -8
  104. data/spec/active_record/integration_spec.rb +0 -23
  105. data/spec/datamapper/controller_activity_logging_spec.rb +0 -17
  106. data/spec/datamapper/controller_spec.rb +0 -8
  107. data/spec/datamapper/user_activity_logging_spec.rb +0 -9
  108. data/spec/mongo_mapper/controller_spec.rb +0 -8
  109. data/spec/mongoid/controller_activity_logging_spec.rb +0 -16
  110. data/spec/mongoid/controller_spec.rb +0 -8
  111. data/spec/rails_app/public/404.html +0 -26
  112. data/spec/rails_app/public/422.html +0 -26
  113. data/spec/rails_app/public/500.html +0 -26
  114. data/spec/rails_app/public/favicon.ico +0 -0
  115. data/spec/rails_app/public/images/rails.png +0 -0
  116. data/spec/rails_app/public/javascripts/application.js +0 -2
  117. data/spec/rails_app/public/javascripts/controls.js +0 -965
  118. data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
  119. data/spec/rails_app/public/javascripts/effects.js +0 -1123
  120. data/spec/rails_app/public/javascripts/prototype.js +0 -6001
  121. data/spec/rails_app/public/javascripts/rails.js +0 -175
  122. data/spec/rails_app/public/robots.txt +0 -5
  123. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  124. data/spec/shared_examples/controller_activity_logging_shared_examples.rb +0 -125
  125. data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -52
  126. data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -62
@@ -0,0 +1,65 @@
1
+ module Sorcery
2
+ module Controller
3
+ module Config
4
+ class << self
5
+ attr_accessor :submodules,
6
+ :user_class, # what class to use as the user class.
7
+ :not_authenticated_action, # what controller action to call for non-authenticated users.
8
+
9
+ :save_return_to_url, # when a non logged in user tries to enter a page that requires
10
+ # login, save the URL he wanted to reach,
11
+ # and send him there after login.
12
+
13
+ :cookie_domain, # set domain option for cookies
14
+
15
+ :login_sources,
16
+ :after_login,
17
+ :after_failed_login,
18
+ :before_logout,
19
+ :after_logout
20
+
21
+ def init!
22
+ @defaults = {
23
+ :@user_class => nil,
24
+ :@submodules => [],
25
+ :@not_authenticated_action => :not_authenticated,
26
+ :@login_sources => [],
27
+ :@after_login => [],
28
+ :@after_failed_login => [],
29
+ :@before_logout => [],
30
+ :@after_logout => [],
31
+ :@save_return_to_url => true,
32
+ :@cookie_domain => nil
33
+ }
34
+ end
35
+
36
+ # Resets all configuration options to their default values.
37
+ def reset!
38
+ @defaults.each do |k,v|
39
+ instance_variable_set(k,v)
40
+ end
41
+ end
42
+
43
+ def update!
44
+ @defaults.each do |k,v|
45
+ instance_variable_set(k,v) if !instance_variable_defined?(k)
46
+ end
47
+ end
48
+
49
+ def user_config(&blk)
50
+ block_given? ? @user_config = blk : @user_config
51
+ end
52
+
53
+ def configure(&blk)
54
+ @configure_blk = blk
55
+ end
56
+
57
+ def configure!
58
+ @configure_blk.call(self) if @configure_blk
59
+ end
60
+ end
61
+ init!
62
+ reset!
63
+ end
64
+ end
65
+ end
@@ -1,13 +1,13 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
- # This submodule keeps track of events such as login, logout,
4
+ # This submodule keeps track of events such as login, logout,
5
5
  # and last activity time, per user.
6
6
  # It helps in estimating which users are active now in the site.
7
- # This cannot be determined absolutely because a user might be
7
+ # This cannot be determined absolutely because a user might be
8
8
  # reading a page without clicking anything for a while.
9
- # This is the controller part of the submodule, which adds hooks
10
- # to register user events,
9
+ # This is the controller part of the submodule, which adds hooks
10
+ # to register user events,
11
11
  # and methods to collect active users data for use in the app.
12
12
  # see Socery::Model::Submodules::ActivityLogging for configuration
13
13
  # options.
@@ -20,7 +20,7 @@ module Sorcery
20
20
  attr_accessor :register_logout_time
21
21
  attr_accessor :register_last_activity_time
22
22
  attr_accessor :register_last_ip_address
23
-
23
+
24
24
  def merge_activity_logging_defaults!
25
25
  @defaults.merge!(:@register_login_time => true,
26
26
  :@register_logout_time => true,
@@ -36,49 +36,44 @@ module Sorcery
36
36
  Config.before_logout << :register_logout_time_to_db
37
37
  base.after_filter :register_last_activity_time_to_db
38
38
  end
39
-
39
+
40
40
  module InstanceMethods
41
41
  # Returns an array of the active users.
42
42
  def current_users
43
+ ActiveSupport::Deprecation.warn("Sorcery: `current_users` method is deprecated. Read more on Github: https://github.com/NoamB/sorcery/issues/602")
44
+
43
45
  user_class.current_users
44
- # A possible patch here:
45
- # we'll add the current_user to the users list if he's not in it
46
- # (can happen when he was inactive for more than activity timeout):
47
- #
48
- # users.unshift!(current_user) if logged_in? && users.find {|u| u.id == current_user.id}.nil?
49
- #
50
- # disadvantages: can hurt performance.
51
46
  end
52
-
47
+
53
48
  protected
54
-
49
+
55
50
  # registers last login time on every login.
56
51
  # This runs as a hook just after a successful login.
57
52
  def register_login_time_to_db(user, credentials)
58
53
  return unless Config.register_login_time
59
- user.update_single_attribute(user.sorcery_config.last_login_at_attribute_name, Time.now.in_time_zone)
54
+ user.set_last_login_at(Time.now.in_time_zone)
60
55
  end
61
-
56
+
62
57
  # registers last logout time on every logout.
63
58
  # This runs as a hook just before a logout.
64
59
  def register_logout_time_to_db(user)
65
60
  return unless Config.register_logout_time
66
- user.update_single_attribute(user.sorcery_config.last_logout_at_attribute_name, Time.now.in_time_zone)
61
+ user.set_last_logout_at(Time.now.in_time_zone)
67
62
  end
68
-
63
+
69
64
  # Updates last activity time on every request.
70
65
  # The only exception is logout - we do not update activity on logout
71
66
  def register_last_activity_time_to_db
72
67
  return unless Config.register_last_activity_time
73
68
  return unless logged_in?
74
- current_user.update_single_attribute(current_user.sorcery_config.last_activity_at_attribute_name, Time.now.in_time_zone)
69
+ current_user.set_last_activity_at(Time.now.in_time_zone)
75
70
  end
76
71
 
77
72
  # Updates IP address on every login.
78
73
  # This runs as a hook just after a successful login.
79
74
  def register_last_ip_address(user, credentials)
80
75
  return unless Config.register_last_ip_address
81
- current_user.update_single_attribute(current_user.sorcery_config.last_login_from_ip_address_name, request.remote_ip)
76
+ current_user.set_last_ip_addess(request.remote_ip)
82
77
  end
83
78
  end
84
79
  end
@@ -14,22 +14,22 @@ module Sorcery
14
14
  Config.after_login << :reset_failed_logins_count!
15
15
  Config.after_failed_login << :update_failed_logins_count!
16
16
  end
17
-
17
+
18
18
  module InstanceMethods
19
-
19
+
20
20
  protected
21
-
21
+
22
22
  # Increments the failed logins counter on every failed login.
23
23
  # Runs as a hook after a failed login.
24
24
  def update_failed_logins_count!(credentials)
25
- user = user_class.find_by_credentials(credentials)
25
+ user = user_class.sorcery_adapter.find_by_credentials(credentials)
26
26
  user.register_failed_login! if user
27
27
  end
28
-
28
+
29
29
  # Resets the failed logins counter.
30
30
  # Runs as a hook after a successful login.
31
31
  def reset_failed_logins_count!(user, credentials)
32
- user.update_many_attributes(user_class.sorcery_config.failed_logins_count_attribute_name => 0)
32
+ user.sorcery_adapter.update_attribute(user_class.sorcery_config.failed_logins_count_attribute_name, 0)
33
33
  end
34
34
  end
35
35
  end
@@ -15,7 +15,10 @@ module Sorcery
15
15
  require 'sorcery/providers/liveid'
16
16
  require 'sorcery/providers/xing'
17
17
  require 'sorcery/providers/github'
18
+ require 'sorcery/providers/heroku'
18
19
  require 'sorcery/providers/google'
20
+ require 'sorcery/providers/jira'
21
+ require 'sorcery/providers/salesforce'
19
22
 
20
23
  Config.module_eval do
21
24
  class << self
@@ -133,15 +136,7 @@ module Sorcery
133
136
  sorcery_fetch_user_hash provider_name
134
137
  config = user_class.sorcery_config
135
138
 
136
- # first check to see if user has a particular authentication already
137
- unless (current_user.send(config.authentications_class.name.underscore.pluralize).send("find_by_#{config.provider_attribute_name}_and_#{config.provider_uid_attribute_name}", provider_name, @user_hash[:uid].to_s))
138
- user = current_user.send(config.authentications_class.name.underscore.pluralize).build(config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name.to_s)
139
- user.sorcery_save(:validate => false)
140
- else
141
- user = false
142
- end
143
-
144
- return user
139
+ current_user.add_provider_to_user(provider_name.to_s, @user_hash[:uid].to_s)
145
140
  end
146
141
 
147
142
  # Initialize new user from provider informations.
@@ -153,13 +148,12 @@ module Sorcery
153
148
 
154
149
  attrs = user_attrs(@provider.user_info_mapping, @user_hash)
155
150
 
156
- user = user_class.new(attrs)
157
- user.send(config.authentications_class.to_s.downcase.pluralize).build(config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name)
151
+ user, saved = user_class.create_and_validate_from_provider(provider_name, @user_hash[:uid], attrs)
158
152
 
159
153
  session[:incomplete_user] = {
160
154
  :provider => {config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name},
161
155
  :user_hash => attrs
162
- } unless user.sorcery_save
156
+ } unless saved
163
157
 
164
158
  return user
165
159
  end
@@ -180,26 +174,12 @@ module Sorcery
180
174
  #
181
175
  # create_from(provider) {|user| user.some_check }
182
176
  #
183
- def create_from(provider_name)
177
+ def create_from(provider_name, &block)
184
178
  sorcery_fetch_user_hash provider_name
185
179
  config = user_class.sorcery_config
186
180
 
187
181
  attrs = user_attrs(@provider.user_info_mapping, @user_hash)
188
-
189
- user_class.transaction do
190
- @user = user_class.new()
191
- attrs.each do |k,v|
192
- @user.send(:"#{k}=", v)
193
- end
194
-
195
- if block_given?
196
- return false unless yield @user
197
- end
198
-
199
- @user.sorcery_save(:validate => false)
200
- user_class.sorcery_config.authentications_class.create!({config.authentications_user_id_attribute_name => @user.id, config.provider_attribute_name => provider_name, config.provider_uid_attribute_name => @user_hash[:uid]})
201
- end
202
- @user
182
+ @user = user_class.create_from_provider(provider_name, @user_hash[:uid], attrs, &block)
203
183
  end
204
184
 
205
185
  def user_attrs(user_info_mapping, user_hash)
@@ -38,7 +38,7 @@ module Sorcery
38
38
  # Override.
39
39
  # logins a user instance, and optionally remembers him.
40
40
  def auto_login(user, should_remember = false)
41
- session[:user_id] = user.id
41
+ session[:user_id] = user.id.to_s
42
42
  @current_user = user
43
43
  remember_me! if should_remember
44
44
  end
@@ -55,10 +55,10 @@ module Sorcery
55
55
  # and logs the user in if found.
56
56
  # Runs as a login source. See 'current_user' method for how it is used.
57
57
  def login_from_cookie
58
- user = cookies.signed[:remember_me_token] && user_class.find_by_remember_me_token(cookies.signed[:remember_me_token])
59
- if user && user.remember_me_token?
58
+ user = cookies.signed[:remember_me_token] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[:remember_me_token])
59
+ if user && user.has_remember_me_token?
60
60
  set_remember_me_cookie!(user)
61
- session[:user_id] = user.id
61
+ session[:user_id] = user.id.to_s
62
62
  @current_user = user
63
63
  else
64
64
  @current_user = false
@@ -9,10 +9,10 @@ module Sorcery
9
9
  Config.module_eval do
10
10
  class << self
11
11
  attr_accessor :session_timeout, # how long in seconds to keep the session alive.
12
-
12
+
13
13
  :session_timeout_from_last_action # use the last action as the beginning of session
14
14
  # timeout.
15
-
15
+
16
16
  def merge_session_timeout_defaults!
17
17
  @defaults.merge!(:@session_timeout => 3600, # 1.hour
18
18
  :@session_timeout_from_last_action => false)
@@ -23,21 +23,21 @@ module Sorcery
23
23
  Config.after_login << :register_login_time
24
24
  base.prepend_before_filter :validate_session
25
25
  end
26
-
26
+
27
27
  module InstanceMethods
28
28
  protected
29
-
29
+
30
30
  # Registers last login to be used as the timeout starting point.
31
31
  # Runs as a hook after a successful login.
32
32
  def register_login_time(user, credentials)
33
33
  session[:login_time] = session[:last_action_time] = Time.now.in_time_zone
34
34
  end
35
-
35
+
36
36
  # Checks if session timeout was reached and expires the current session if so.
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.to_time > Config.session_timeout)
40
+ if session_to_use && sorcery_session_expired?(session_to_use.to_time)
41
41
  reset_sorcery_session
42
42
  @current_user = nil
43
43
  else
@@ -45,6 +45,10 @@ module Sorcery
45
45
  end
46
46
  end
47
47
 
48
+ def sorcery_session_expired?(time)
49
+ Time.now.in_time_zone - time > Config.session_timeout
50
+ end
51
+
48
52
  end
49
53
  end
50
54
  end
@@ -19,17 +19,28 @@ module Sorcery
19
19
  # This runs the options block set in the initializer on the model class.
20
20
  ::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
21
21
 
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)
25
-
22
+ define_base_fields
26
23
  init_orm_hooks!
27
24
 
28
25
  @sorcery_config.after_config << :add_config_inheritance if @sorcery_config.subclasses_inherit_config
29
26
  @sorcery_config.after_config.each { |c| send(c) }
30
27
  end
31
28
 
32
- protected
29
+ private
30
+
31
+ def define_base_fields
32
+ self.class_eval do
33
+ sorcery_config.username_attribute_names.each do |username|
34
+ sorcery_adapter.define_field username, String, length: 255
35
+ end
36
+ unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
37
+ sorcery_adapter.define_field sorcery_config.email_attribute_name, String, length: 255
38
+ end
39
+ sorcery_adapter.define_field sorcery_config.crypted_password_attribute_name, String, length: 255
40
+ sorcery_adapter.define_field sorcery_config.salt_attribute_name, String, length: 255
41
+ end
42
+
43
+ end
33
44
 
34
45
  # includes required submodules into the model class,
35
46
  # which usually is called User.
@@ -47,77 +58,17 @@ module Sorcery
47
58
  end
48
59
  end
49
60
 
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
62
-
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
61
  # add virtual password accessor and ORM callbacks.
90
62
  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
63
+ sorcery_adapter.define_callback :before, :validation, :encrypt_password, if: Proc.new {|record|
64
+ record.send(sorcery_config.password_attribute_name).present?
65
+ }
106
66
 
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
118
- end
119
- end
120
- end
67
+ sorcery_adapter.define_callback :after, :save, :clear_virtual_password, if: Proc.new {|record|
68
+ record.send(sorcery_config.password_attribute_name).present?
69
+ }
70
+
71
+ attr_accessor sorcery_config.password_attribute_name
121
72
  end
122
73
 
123
74
  module ClassMethods
@@ -139,12 +90,11 @@ module Sorcery
139
90
  credentials[0].downcase!
140
91
  end
141
92
 
142
- user = find_by_credentials(credentials)
93
+ user = sorcery_adapter.find_by_credentials(credentials)
143
94
 
144
95
  set_encryption_attributes
145
96
 
146
- _salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
147
- user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && credentials_match?(user.send(@sorcery_config.crypted_password_attribute_name),credentials[1],_salt)
97
+ user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && user.valid_password?(credentials[1])
148
98
  end
149
99
 
150
100
  # encrypt tokens using current encryption_provider.
@@ -163,13 +113,7 @@ module Sorcery
163
113
  @sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches
164
114
  @sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token
165
115
  end
166
-
167
- # Calls the configured encryption provider to compare the supplied password with the encrypted one.
168
- def credentials_match?(crypted, *tokens)
169
- return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
170
- @sorcery_config.encryption_provider.matches?(crypted, *tokens)
171
- end
172
-
116
+
173
117
  def add_config_inheritance
174
118
  self.class_eval do
175
119
  def self.inherited(subclass)
@@ -198,6 +142,16 @@ module Sorcery
198
142
  send(sorcery_config.crypted_password_attribute_name).nil?
199
143
  end
200
144
 
145
+ # Calls the configured encryption provider to compare the supplied password with the encrypted one.
146
+ def valid_password?(pass)
147
+ _crypted = self.send(sorcery_config.crypted_password_attribute_name)
148
+ return _crypted == pass if sorcery_config.encryption_provider.nil?
149
+
150
+ _salt = self.send(sorcery_config.salt_attribute_name) unless sorcery_config.salt_attribute_name.nil?
151
+
152
+ sorcery_config.encryption_provider.matches?(_crypted, pass, _salt)
153
+ end
154
+
201
155
  protected
202
156
 
203
157
  # creates new salt and saves it.
@@ -223,100 +177,14 @@ module Sorcery
223
177
  config = sorcery_config
224
178
  mail = config.send(mailer).send(config.send(method),self)
225
179
  if defined?(ActionMailer) and config.send(mailer).kind_of?(Class) and config.send(mailer) < ActionMailer::Base
226
- mail.deliver
227
- end
228
- end
229
- end
230
-
231
- # Each class which calls 'activate_sorcery!' receives an instance of this class.
232
- # Every submodule which gets loaded may add accessors to this class so that all
233
- # options will be configured from a single place.
234
- class Config
235
-
236
- attr_accessor :username_attribute_names, # change default username attribute, for example, to use :email
237
- # as the login.
238
-
239
- :password_attribute_name, # change *virtual* password attribute, the one which is used
240
- # until an encrypted one is generated.
241
-
242
- :email_attribute_name, # change default email attribute.
243
-
244
- :downcase_username_before_authenticating, # downcase the username before trying to authenticate, default is false
245
-
246
- :crypted_password_attribute_name, # change default crypted_password attribute.
247
- :salt_join_token, # what pattern to use to join the password with the salt
248
- :salt_attribute_name, # change default salt attribute.
249
- :stretches, # how many times to apply encryption to the password.
250
- :encryption_key, # encryption key used to encrypt reversible encryptions such as
251
- # AES256.
252
-
253
- :subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for
254
- # ActiveRecord's STI.
255
-
256
- :submodules, # configured in config/application.rb
257
- :before_authenticate, # an array of method names to call before authentication
258
- # completes. used internally.
259
-
260
- :after_config # an array of method names to call after configuration by user.
261
- # used internally.
262
-
263
- attr_reader :encryption_provider, # change default encryption_provider.
264
- :custom_encryption_provider, # use an external encryption class.
265
- :encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below
266
- # for available options.
267
-
268
- def initialize
269
- @defaults = {
270
- :@submodules => [],
271
- :@username_attribute_names => [:email],
272
- :@password_attribute_name => :password,
273
- :@downcase_username_before_authenticating => false,
274
- :@email_attribute_name => :email,
275
- :@crypted_password_attribute_name => :crypted_password,
276
- :@encryption_algorithm => :bcrypt,
277
- :@encryption_provider => CryptoProviders::BCrypt,
278
- :@custom_encryption_provider => nil,
279
- :@encryption_key => nil,
280
- :@salt_join_token => "",
281
- :@salt_attribute_name => :salt,
282
- :@stretches => nil,
283
- :@subclasses_inherit_config => false,
284
- :@before_authenticate => [],
285
- :@after_config => []
286
- }
287
- reset!
288
- end
289
-
290
- # Resets all configuration options to their default values.
291
- def reset!
292
- @defaults.each do |k,v|
293
- instance_variable_set(k,v)
294
- end
295
- end
296
-
297
- def username_attribute_names=(fields)
298
- @username_attribute_names = fields.kind_of?(Array) ? fields : [fields]
299
- end
300
-
301
- def custom_encryption_provider=(provider)
302
- @custom_encryption_provider = @encryption_provider = provider
303
- end
304
-
305
- def encryption_algorithm=(algo)
306
- @encryption_algorithm = algo
307
- @encryption_provider = case @encryption_algorithm.to_sym
308
- when :none then nil
309
- when :md5 then CryptoProviders::MD5
310
- when :sha1 then CryptoProviders::SHA1
311
- when :sha256 then CryptoProviders::SHA256
312
- when :sha512 then CryptoProviders::SHA512
313
- when :aes256 then CryptoProviders::AES256
314
- when :bcrypt then CryptoProviders::BCrypt
315
- when :custom then @custom_encryption_provider
316
- else raise ArgumentError.new("Encryption algorithm supplied, #{algo}, is invalid")
180
+ # Rails 4.2 deprecates #deliver
181
+ if mail.respond_to?(:deliver_now)
182
+ mail.deliver_now
183
+ else
184
+ mail.deliver
185
+ end
317
186
  end
318
187
  end
319
-
320
188
  end
321
189
 
322
190
  end