sorcery 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/Gemfile +4 -3
  2. data/Gemfile.lock +16 -13
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +77 -63
  5. data/Rakefile +7 -13
  6. data/VERSION +1 -1
  7. data/lib/sorcery/controller/submodules/activity_logging.rb +58 -0
  8. data/lib/sorcery/controller/submodules/brute_force_protection.rb +15 -69
  9. data/lib/sorcery/controller/submodules/http_basic_auth.rb +65 -0
  10. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +25 -0
  11. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +23 -0
  12. data/lib/sorcery/controller/submodules/oauth/providers/facebook.rb +64 -0
  13. data/lib/sorcery/controller/submodules/oauth/providers/twitter.rb +61 -0
  14. data/lib/sorcery/controller/submodules/oauth.rb +95 -0
  15. data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
  16. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -2
  17. data/lib/sorcery/controller.rb +40 -22
  18. data/lib/sorcery/crypto_providers/bcrypt.rb +3 -7
  19. data/lib/sorcery/engine.rb +9 -2
  20. data/lib/sorcery/model/submodules/activity_logging.rb +40 -0
  21. data/lib/sorcery/model/submodules/brute_force_protection.rb +79 -0
  22. data/lib/sorcery/model/submodules/oauth.rb +53 -0
  23. data/lib/sorcery/model/submodules/remember_me.rb +6 -2
  24. data/lib/sorcery/model/submodules/reset_password.rb +96 -0
  25. data/lib/sorcery/model/submodules/user_activation.rb +44 -23
  26. data/lib/sorcery/model/temporary_token.rb +22 -0
  27. data/lib/sorcery/model.rb +13 -6
  28. data/lib/sorcery/test_helpers.rb +84 -0
  29. data/lib/sorcery.rb +17 -1
  30. data/sorcery.gemspec +85 -41
  31. data/spec/Gemfile +3 -2
  32. data/spec/Gemfile.lock +15 -2
  33. data/spec/rails3/app_root/.rspec +1 -0
  34. data/spec/rails3/{Gemfile → app_root/Gemfile} +5 -3
  35. data/spec/rails3/{Gemfile.lock → app_root/Gemfile.lock} +25 -2
  36. data/spec/rails3/app_root/app/controllers/application_controller.rb +48 -2
  37. data/spec/rails3/app_root/app/models/authentication.rb +3 -0
  38. data/spec/rails3/app_root/app/models/user.rb +4 -1
  39. data/spec/rails3/app_root/config/application.rb +1 -3
  40. data/spec/rails3/app_root/config/routes.rb +1 -9
  41. data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +6 -4
  42. data/spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  43. data/spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  44. data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +4 -4
  45. data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
  46. data/spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  47. data/spec/rails3/app_root/spec/controller_activity_logging_spec.rb +84 -0
  48. data/spec/rails3/app_root/spec/controller_brute_force_protection_spec.rb +65 -0
  49. data/spec/rails3/app_root/spec/controller_http_basic_auth_spec.rb +50 -0
  50. data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +117 -0
  51. data/spec/rails3/app_root/spec/controller_oauth_spec.rb +117 -0
  52. data/spec/rails3/{controller_remember_me_spec.rb → app_root/spec/controller_remember_me_spec.rb} +4 -4
  53. data/spec/rails3/{controller_session_timeout_spec.rb → app_root/spec/controller_session_timeout_spec.rb} +5 -4
  54. data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +23 -16
  55. data/spec/rails3/app_root/spec/spec_helper.orig.rb +27 -0
  56. data/spec/rails3/app_root/spec/spec_helper.rb +61 -0
  57. data/spec/rails3/{user_activation_spec.rb → app_root/spec/user_activation_spec.rb} +62 -22
  58. data/spec/rails3/app_root/spec/user_activity_logging_spec.rb +36 -0
  59. data/spec/rails3/app_root/spec/user_brute_force_protection_spec.rb +76 -0
  60. data/spec/rails3/app_root/spec/user_oauth_spec.rb +39 -0
  61. data/spec/rails3/{user_remember_me_spec.rb → app_root/spec/user_remember_me_spec.rb} +4 -4
  62. data/spec/rails3/app_root/spec/user_reset_password_spec.rb +178 -0
  63. data/spec/rails3/{user_spec.rb → app_root/spec/user_spec.rb} +68 -38
  64. metadata +145 -61
  65. data/features/support/env.rb +0 -13
  66. data/lib/sorcery/model/submodules/password_reset.rb +0 -64
  67. data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +0 -9
  68. data/spec/rails3/app_root/test/fixtures/users.yml +0 -9
  69. data/spec/rails3/app_root/test/performance/browsing_test.rb +0 -9
  70. data/spec/rails3/app_root/test/test_helper.rb +0 -13
  71. data/spec/rails3/app_root/test/unit/user_test.rb +0 -8
  72. data/spec/rails3/controller_brute_force_protection_spec.rb +0 -72
  73. data/spec/rails3/spec_helper.rb +0 -115
  74. data/spec/rails3/user_password_reset_spec.rb +0 -76
  75. /data/spec/rails3/{Rakefile → app_root/Rakefile} +0 -0
@@ -1,6 +1,8 @@
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 be automatically logged in to the site on every visit,
5
+ # until the cookie expires.
4
6
  module RememberMe
5
7
  def self.included(base)
6
8
  base.sorcery_config.class_eval do
@@ -22,13 +24,15 @@ module Sorcery
22
24
  end
23
25
 
24
26
  module InstanceMethods
27
+ # You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
25
28
  def remember_me!
26
29
  config = sorcery_config
27
- self.send(:"#{config.remember_me_token_attribute_name}=", generate_random_code)
30
+ self.send(:"#{config.remember_me_token_attribute_name}=", generate_random_token)
28
31
  self.send(:"#{config.remember_me_token_expires_at_attribute_name}=", Time.now + config.remember_me_for)
29
32
  self.save!(:validate => false)
30
33
  end
31
-
34
+
35
+ # You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method.
32
36
  def forget_me!
33
37
  config = sorcery_config
34
38
  self.send(:"#{config.remember_me_token_attribute_name}=", nil)
@@ -0,0 +1,96 @@
1
+ module Sorcery
2
+ module Model
3
+ module Submodules
4
+ # This submodule adds the ability to reset password via email confirmation.
5
+ # When the user requests an email is sent to him with a url.
6
+ # The url includes a token, which is also saved with the user's record in the db.
7
+ # The token has configurable expiration.
8
+ # When the user clicks the url in the email, providing the token has not yet expired, he will be able to reset his password via a form.
9
+ #
10
+ # When using this submodule, supplying a mailer is mandatory.
11
+ module ResetPassword
12
+ def self.included(base)
13
+ base.sorcery_config.class_eval do
14
+ attr_accessor :reset_password_token_attribute_name, # reset password code attribute name.
15
+ :reset_password_token_expires_at_attribute_name, # expires at attribute name.
16
+ :reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering protection.
17
+ :reset_password_mailer, # mailer class. Needed.
18
+ :reset_password_email_method_name, # reset password email method on your mailer class.
19
+ :reset_password_expiration_period, # how many seconds before the reset request expires. nil for never expires.
20
+ :reset_password_time_between_emails # hammering protection, how long to wait before allowing another email to be sent.
21
+
22
+ end
23
+
24
+ base.sorcery_config.instance_eval do
25
+ @defaults.merge!(:@reset_password_token_attribute_name => :reset_password_token,
26
+ :@reset_password_token_expires_at_attribute_name => :reset_password_token_expires_at,
27
+ :@reset_password_email_sent_at_attribute_name => :reset_password_email_sent_at,
28
+ :@reset_password_mailer => nil,
29
+ :@reset_password_email_method_name => :reset_password_email,
30
+ :@reset_password_expiration_period => nil,
31
+ :@reset_password_time_between_emails => 5.minutes )
32
+
33
+ reset!
34
+ end
35
+
36
+ base.sorcery_config.after_config << :validate_mailer_defined
37
+
38
+ base.extend(ClassMethods)
39
+ base.send(:include, TemporaryToken)
40
+ base.send(:include, InstanceMethods)
41
+ end
42
+
43
+ module ClassMethods
44
+ # Find user by token, also checks for expiration.
45
+ # Returns the user if token found and is valid.
46
+ def load_from_reset_password_token(token)
47
+ token_attr_name = @sorcery_config.reset_password_token_attribute_name
48
+ token_expiration_date_attr = @sorcery_config.reset_password_token_expires_at_attribute_name
49
+ load_from_token(token, token_attr_name, token_expiration_date_attr)
50
+ end
51
+
52
+ protected
53
+
54
+ # This submodule requires the developer to define his own mailer class to be used by it.
55
+ def validate_mailer_defined
56
+ msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)."
57
+ raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
58
+ end
59
+
60
+ end
61
+
62
+ module InstanceMethods
63
+ # generates a reset code with expiration and sends an email to the user.
64
+ def deliver_reset_password_instructions!
65
+ config = sorcery_config
66
+ # hammering protection
67
+ return if config.reset_password_time_between_emails && 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.ago.utc
68
+ self.send(:"#{config.reset_password_token_attribute_name}=", generate_random_token)
69
+ self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", Time.now.utc + config.reset_password_expiration_period) if config.reset_password_expiration_period
70
+ self.send(:"#{config.reset_password_email_sent_at_attribute_name}=", Time.now.utc)
71
+ self.class.transaction do
72
+ self.save!(:validate => false)
73
+ generic_send_email(:reset_password_email_method_name, :reset_password_mailer)
74
+ end
75
+ end
76
+
77
+ # Clears token and tries to update the new password for the user.
78
+ def reset_password!(params)
79
+ clear_reset_password_token
80
+ update_attributes(params)
81
+ end
82
+
83
+ protected
84
+
85
+ # Clears the token.
86
+ def clear_reset_password_token
87
+ config = sorcery_config
88
+ self.send(:"#{config.reset_password_token_attribute_name}=", nil)
89
+ self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
@@ -8,27 +8,33 @@ module Sorcery
8
8
  module UserActivation
9
9
  def self.included(base)
10
10
  base.sorcery_config.class_eval do
11
- attr_accessor :activation_state_attribute_name, # the attribute name to hold activation state (active/pending).
12
- :activation_code_attribute_name, # the attribute name to hold activation code (sent by email).
13
- :sorcery_mailer, # your mailer class. Needed.
14
- :activation_needed_email_method_name, # activation needed email method on your mailer class.
15
- :activation_success_email_method_name, # activation success email method on your mailer class.
16
- :prevent_non_active_users_to_login # do you want to prevent or allow users that did not activate by email to login?
11
+ attr_accessor :activation_state_attribute_name, # the attribute name to hold activation state (active/pending).
12
+ :activation_token_attribute_name, # the attribute name to hold activation code (sent by email).
13
+ :activation_token_expires_at_attribute_name, # the attribute name to hold activation code expiration date.
14
+ :activation_token_expiration_period, # how many seconds before the activation code expires. nil for never expires.
15
+ :user_activation_mailer, # your mailer class. Required.
16
+ :activation_needed_email_method_name, # activation needed email method on your mailer class.
17
+ :activation_success_email_method_name, # activation success email method on your mailer class.
18
+ :prevent_non_active_users_to_login # do you want to prevent or allow users that did not activate by email to login?
17
19
  end
18
20
 
19
21
  base.sorcery_config.instance_eval do
20
- @defaults.merge!(:@activation_state_attribute_name => :activation_state,
21
- :@activation_code_attribute_name => :activation_code,
22
- :@sorcery_mailer => nil,
23
- :@activation_needed_email_method_name => :activation_needed_email,
24
- :@activation_success_email_method_name => :activation_success_email,
25
- :@prevent_non_active_users_to_login => true)
22
+ @defaults.merge!(:@activation_state_attribute_name => :activation_state,
23
+ :@activation_token_attribute_name => :activation_token,
24
+ :@activation_token_expires_at_attribute_name => :activation_token_expires_at,
25
+ :@activation_token_expiration_period => nil,
26
+ :@user_activation_mailer => nil,
27
+ :@activation_needed_email_method_name => :activation_needed_email,
28
+ :@activation_success_email_method_name => :activation_success_email,
29
+ :@prevent_non_active_users_to_login => true)
26
30
  reset!
27
31
  end
28
32
 
29
33
  base.class_eval do
30
- before_create :setup_activation
31
- after_create :send_activation_needed_email!
34
+ # don't setup activation if no password supplied - this user is created automatically
35
+ before_create :setup_activation, :if => Proc.new { |user| user.send(sorcery_config.password_attribute_name).present? }
36
+ # don't send activation needed email if no crypted password created - this user is external (OAuth etc.)
37
+ after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external?}
32
38
  end
33
39
 
34
40
  base.sorcery_config.after_config << :validate_mailer_defined
@@ -36,40 +42,55 @@ module Sorcery
36
42
  base.sorcery_config.before_authenticate << :prevent_non_active_login
37
43
 
38
44
  base.extend(ClassMethods)
45
+ base.send(:include, TemporaryToken)
39
46
  base.send(:include, InstanceMethods)
40
47
  end
41
48
 
42
49
  module ClassMethods
50
+ # Find user by token, also checks for expiration.
51
+ # Returns the user if token found and is valid.
52
+ def load_from_activation_token(token)
53
+ token_attr_name = @sorcery_config.activation_token_attribute_name
54
+ token_expiration_date_attr = @sorcery_config.activation_token_expires_at_attribute_name
55
+ load_from_token(token, token_attr_name, token_expiration_date_attr)
56
+ end
57
+
58
+ protected
59
+
60
+ # This submodule requires the developer to define his own mailer class to be used by it.
43
61
  def validate_mailer_defined
44
- msg = "To use user_activation submodule, you must define a mailer (config.sorcery_mailer = YourMailerClass)."
45
- raise ArgumentError, msg if @sorcery_config.sorcery_mailer == nil
62
+ msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
63
+ raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
46
64
  end
47
65
  end
48
66
 
49
67
  module InstanceMethods
68
+ # clears activation code, sets the user as 'active' and optionaly sends a success email.
50
69
  def activate!
51
70
  config = sorcery_config
52
- self.send(:"#{config.activation_code_attribute_name}=", nil)
71
+ self.send(:"#{config.activation_token_attribute_name}=", nil)
53
72
  self.send(:"#{config.activation_state_attribute_name}=", "active")
54
- send_activation_success_email!
73
+ send_activation_success_email! unless self.external?
55
74
  save!(:validate => false) # don't run validations
56
75
  end
57
-
76
+
58
77
  protected
59
78
 
60
79
  def setup_activation
61
80
  config = sorcery_config
62
- generated_activation_code = CryptoProviders::SHA1.encrypt( Time.now.to_s.split(//).sort_by {rand}.join )
63
- self.send(:"#{config.activation_code_attribute_name}=", generated_activation_code)
81
+ generated_activation_token = generate_random_token
82
+ self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
64
83
  self.send(:"#{config.activation_state_attribute_name}=", "pending")
84
+ self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.utc + config.activation_token_expiration_period) if config.activation_token_expiration_period
65
85
  end
66
86
 
87
+ # called automatically after user initial creation.
67
88
  def send_activation_needed_email!
68
- generic_send_email(:activation_needed_email_method_name) unless sorcery_config.activation_needed_email_method_name.nil?
89
+ generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil?
69
90
  end
70
91
 
71
92
  def send_activation_success_email!
72
- generic_send_email(:activation_success_email_method_name) unless sorcery_config.activation_success_email_method_name.nil?
93
+ generic_send_email(:activation_success_email_method_name, :user_activation_mailer) unless sorcery_config.activation_success_email_method_name.nil?
73
94
  end
74
95
 
75
96
  def prevent_non_active_login
@@ -0,0 +1,22 @@
1
+ module Sorcery
2
+ module Model
3
+ # This module encapsulates the logic for temporary token.
4
+ # A temporary token is created to identify a user in scenarios such as reseting password and activating the user by email.
5
+ module TemporaryToken
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def load_from_token(token, token_attr_name, token_expiration_date_attr)
12
+ return nil if token.blank?
13
+ user = where("#{token_attr_name} = ?", token).first
14
+ if !user.blank? && !user.send(token_expiration_date_attr).nil?
15
+ return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
16
+ end
17
+ user
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/sorcery/model.rb CHANGED
@@ -55,7 +55,8 @@ module Sorcery
55
55
  _salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
56
56
  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)
57
57
  end
58
-
58
+
59
+ # Calls the configured encryption provider to compare the supplied password with the encrypted one.
59
60
  def credentials_match?(crypted, *tokens)
60
61
  return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
61
62
  @sorcery_config.encryption_provider.matches?(crypted, *tokens)
@@ -78,13 +79,19 @@ module Sorcery
78
79
  self.class.sorcery_config
79
80
  end
80
81
 
82
+ # identifies whether this user is regular, i.e. we hold his credentials in our db,
83
+ # or that he is external, and his credentials are saved elsewhere (twitter/facebook etc.).
84
+ def external?
85
+ send(sorcery_config.crypted_password_attribute_name).nil?
86
+ end
87
+
81
88
  protected
82
89
 
83
90
  # creates new salt and saves it.
84
91
  # encrypts password with salt and save it.
85
92
  def encrypt_password
86
93
  config = sorcery_config
87
- new_salt = self.send(:"#{config.salt_attribute_name}=", generate_random_code) if !config.salt_attribute_name.nil?
94
+ new_salt = self.send(:"#{config.salt_attribute_name}=", generate_random_token) if !config.salt_attribute_name.nil?
88
95
  self.send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(self.send(config.password_attribute_name),new_salt))
89
96
  end
90
97
 
@@ -95,16 +102,16 @@ module Sorcery
95
102
 
96
103
  # calls the requested email method on the configured mailer
97
104
  # supports both the ActionMailer 3 way of calling, and the plain old Ruby object way.
98
- def generic_send_email(method)
105
+ def generic_send_email(method, mailer)
99
106
  config = sorcery_config
100
- mail = config.sorcery_mailer.send(config.send(method),self)
101
- if defined?(ActionMailer) and config.sorcery_mailer.superclass == ActionMailer::Base
107
+ mail = config.send(mailer).send(config.send(method),self)
108
+ if defined?(ActionMailer) and config.send(mailer).superclass == ActionMailer::Base
102
109
  mail.deliver
103
110
  end
104
111
  end
105
112
 
106
113
  # Random code, used for salt and temporary tokens.
107
- def generate_random_code
114
+ def generate_random_token
108
115
  return Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
109
116
  end
110
117
  end
@@ -0,0 +1,84 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
4
+
5
+ def create_new_user(attributes_hash = nil)
6
+ user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
7
+ @user = User.new(user_attributes_hash)
8
+ @user.save!
9
+ @user
10
+ end
11
+
12
+ def create_new_external_user(provider, attributes_hash = nil)
13
+ user_attributes_hash = attributes_hash || {:username => 'gizmo', :authentications_attributes => [{:provider => provider, :uid => 123}]}
14
+ @user = User.new(user_attributes_hash)
15
+ @user.save!
16
+ @user
17
+ end
18
+
19
+ def login_user(user = nil)
20
+ user ||= @user
21
+ subject.send(:login_user,user)
22
+ subject.send(:after_login!,user,[user.username,'secret'])
23
+ end
24
+
25
+ def logout_user
26
+ subject.send(:logout)
27
+ end
28
+
29
+ def clear_user_without_logout
30
+ subject.instance_variable_set(:@current_user,nil)
31
+ end
32
+
33
+ def sorcery_reload!(submodules = [], options = {})
34
+ reload_user_class
35
+
36
+ # return to no-module configuration
37
+ ::Sorcery::Controller::Config.init!
38
+ ::Sorcery::Controller::Config.reset!
39
+
40
+ # remove all plugin before_filters so they won't fail other tests.
41
+ # I don't like this way, but I didn't find another.
42
+ # hopefully it won't break until Rails 4.
43
+ ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
44
+
45
+ # configure
46
+ ::Sorcery::Controller::Config.submodules = submodules
47
+ ::Sorcery::Controller::Config.user_class = nil
48
+ ActionController::Base.send(:include,::Sorcery::Controller)
49
+
50
+ User.activate_sorcery! do |config|
51
+ options.each do |property,value|
52
+ config.send(:"#{property}=", value)
53
+ end
54
+ end
55
+ end
56
+
57
+ def sorcery_model_property_set(property, *values)
58
+ User.class_eval do
59
+ sorcery_config.send(:"#{property}=", *values)
60
+ end
61
+ end
62
+
63
+ def sorcery_controller_property_set(property, value)
64
+ ApplicationController.activate_sorcery! do |config|
65
+ config.send(:"#{property}=", value)
66
+ end
67
+ end
68
+
69
+ def sorcery_controller_oauth_property_set(provider, property, value)
70
+ ApplicationController.activate_sorcery! do |config|
71
+ config.send(provider).send(:"#{property}=", value)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # reload user class between specs
78
+ # so it will be possible to test the different submodules in isolation
79
+ def reload_user_class
80
+ Object.send(:remove_const,:User)
81
+ load 'user.rb'
82
+ end
83
+ end
84
+ end
data/lib/sorcery.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  module Sorcery
2
2
  autoload :Model, 'sorcery/model'
3
3
  module Model
4
+ autoload :TemporaryToken, 'sorcery/model/temporary_token'
4
5
  module Submodules
5
6
  autoload :UserActivation, 'sorcery/model/submodules/user_activation'
6
- autoload :PasswordReset, 'sorcery/model/submodules/password_reset'
7
+ autoload :ResetPassword, 'sorcery/model/submodules/reset_password'
7
8
  autoload :RememberMe, 'sorcery/model/submodules/remember_me'
9
+ autoload :ActivityLogging, 'sorcery/model/submodules/activity_logging'
10
+ autoload :BruteForceProtection, 'sorcery/model/submodules/brute_force_protection'
11
+ autoload :Oauth, 'sorcery/model/submodules/oauth'
8
12
  end
9
13
  end
10
14
  autoload :Controller, 'sorcery/controller'
@@ -13,6 +17,17 @@ module Sorcery
13
17
  autoload :RememberMe, 'sorcery/controller/submodules/remember_me'
14
18
  autoload :SessionTimeout, 'sorcery/controller/submodules/session_timeout'
15
19
  autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
20
+ autoload :HttpBasicAuth, 'sorcery/controller/submodules/http_basic_auth'
21
+ autoload :ActivityLogging, 'sorcery/controller/submodules/activity_logging'
22
+ autoload :Oauth, 'sorcery/controller/submodules/oauth'
23
+ module Oauth
24
+ autoload :Oauth1, 'sorcery/controller/submodules/oauth/oauth1'
25
+ autoload :Oauth2, 'sorcery/controller/submodules/oauth/oauth2'
26
+ module Providers
27
+ autoload :Twitter, 'sorcery/controller/submodules/oauth/providers/twitter'
28
+ autoload :Facebook, 'sorcery/controller/submodules/oauth/providers/facebook'
29
+ end
30
+ end
16
31
  end
17
32
  end
18
33
  module CryptoProviders
@@ -23,6 +38,7 @@ module Sorcery
23
38
  autoload :SHA256, 'sorcery/crypto_providers/sha256'
24
39
  autoload :SHA512, 'sorcery/crypto_providers/sha512'
25
40
  end
41
+ autoload :TestHelpers, 'sorcery/test_helpers'
26
42
 
27
43
  require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
28
44
  end