authlogic 4.4.2 → 5.0.3

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 (147) hide show
  1. checksums.yaml +5 -5
  2. data/lib/authlogic.rb +4 -28
  3. data/lib/authlogic/acts_as_authentic/base.rb +3 -18
  4. data/lib/authlogic/acts_as_authentic/email.rb +3 -170
  5. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +3 -1
  6. data/lib/authlogic/acts_as_authentic/login.rb +7 -174
  7. data/lib/authlogic/acts_as_authentic/magic_columns.rb +7 -4
  8. data/lib/authlogic/acts_as_authentic/password.rb +54 -253
  9. data/lib/authlogic/acts_as_authentic/perishable_token.rb +8 -5
  10. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -4
  11. data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
  12. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +36 -20
  13. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +8 -6
  14. data/lib/authlogic/acts_as_authentic/single_access_token.rb +10 -8
  15. data/lib/authlogic/config.rb +9 -1
  16. data/lib/authlogic/controller_adapters/abstract_adapter.rb +7 -4
  17. data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
  18. data/lib/authlogic/controller_adapters/rails_adapter.rb +19 -19
  19. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
  20. data/lib/authlogic/cookie_credentials.rb +63 -0
  21. data/lib/authlogic/crypto_providers.rb +5 -20
  22. data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
  23. data/lib/authlogic/crypto_providers/md5.rb +3 -6
  24. data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
  25. data/lib/authlogic/crypto_providers/sha1.rb +4 -6
  26. data/lib/authlogic/crypto_providers/sha256.rb +2 -0
  27. data/lib/authlogic/crypto_providers/sha512.rb +6 -5
  28. data/lib/authlogic/i18n.rb +3 -1
  29. data/lib/authlogic/i18n/translator.rb +3 -0
  30. data/lib/authlogic/random.rb +2 -0
  31. data/lib/authlogic/session/base.rb +2087 -39
  32. data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
  33. data/lib/authlogic/test_case.rb +4 -0
  34. data/lib/authlogic/test_case/mock_controller.rb +2 -0
  35. data/lib/authlogic/test_case/mock_cookie_jar.rb +7 -0
  36. data/lib/authlogic/test_case/mock_logger.rb +2 -0
  37. data/lib/authlogic/test_case/mock_request.rb +2 -0
  38. data/lib/authlogic/test_case/rails_request_adapter.rb +2 -0
  39. data/lib/authlogic/version.rb +2 -1
  40. metadata +136 -182
  41. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
  42. data/.github/ISSUE_TEMPLATE/feature_proposal.md +0 -32
  43. data/.github/triage.md +0 -86
  44. data/.gitignore +0 -15
  45. data/.rubocop.yml +0 -133
  46. data/.rubocop_todo.yml +0 -74
  47. data/.travis.yml +0 -24
  48. data/CHANGELOG.md +0 -326
  49. data/CONTRIBUTING.md +0 -91
  50. data/Gemfile +0 -6
  51. data/LICENSE +0 -20
  52. data/README.md +0 -439
  53. data/Rakefile +0 -21
  54. data/UPGRADING.md +0 -22
  55. data/authlogic.gemspec +0 -40
  56. data/doc/use_normal_rails_validation.md +0 -82
  57. data/gemfiles/Gemfile.rails-4.2.x +0 -6
  58. data/gemfiles/Gemfile.rails-5.1.x +0 -6
  59. data/gemfiles/Gemfile.rails-5.2.x +0 -6
  60. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -106
  61. data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -35
  62. data/lib/authlogic/authenticates_many/association.rb +0 -50
  63. data/lib/authlogic/authenticates_many/base.rb +0 -81
  64. data/lib/authlogic/crypto_providers/aes256.rb +0 -71
  65. data/lib/authlogic/crypto_providers/wordpress.rb +0 -72
  66. data/lib/authlogic/regex.rb +0 -79
  67. data/lib/authlogic/session/activation.rb +0 -73
  68. data/lib/authlogic/session/active_record_trickery.rb +0 -65
  69. data/lib/authlogic/session/brute_force_protection.rb +0 -127
  70. data/lib/authlogic/session/callbacks.rb +0 -153
  71. data/lib/authlogic/session/cookies.rb +0 -296
  72. data/lib/authlogic/session/existence.rb +0 -103
  73. data/lib/authlogic/session/foundation.rb +0 -105
  74. data/lib/authlogic/session/http_auth.rb +0 -107
  75. data/lib/authlogic/session/id.rb +0 -53
  76. data/lib/authlogic/session/klass.rb +0 -73
  77. data/lib/authlogic/session/magic_columns.rb +0 -119
  78. data/lib/authlogic/session/magic_states.rb +0 -82
  79. data/lib/authlogic/session/params.rb +0 -130
  80. data/lib/authlogic/session/password.rb +0 -318
  81. data/lib/authlogic/session/perishable_token.rb +0 -24
  82. data/lib/authlogic/session/persistence.rb +0 -77
  83. data/lib/authlogic/session/priority_record.rb +0 -38
  84. data/lib/authlogic/session/scopes.rb +0 -138
  85. data/lib/authlogic/session/session.rb +0 -77
  86. data/lib/authlogic/session/timeout.rb +0 -103
  87. data/lib/authlogic/session/unauthorized_record.rb +0 -56
  88. data/lib/authlogic/session/validation.rb +0 -93
  89. data/test/acts_as_authentic_test/base_test.rb +0 -27
  90. data/test/acts_as_authentic_test/email_test.rb +0 -241
  91. data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -64
  92. data/test/acts_as_authentic_test/login_test.rb +0 -153
  93. data/test/acts_as_authentic_test/magic_columns_test.rb +0 -29
  94. data/test/acts_as_authentic_test/password_test.rb +0 -263
  95. data/test/acts_as_authentic_test/perishable_token_test.rb +0 -98
  96. data/test/acts_as_authentic_test/persistence_token_test.rb +0 -62
  97. data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -48
  98. data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -150
  99. data/test/acts_as_authentic_test/single_access_test.rb +0 -46
  100. data/test/adapter_test.rb +0 -23
  101. data/test/authenticates_many_test.rb +0 -33
  102. data/test/config_test.rb +0 -38
  103. data/test/crypto_provider_test/aes256_test.rb +0 -16
  104. data/test/crypto_provider_test/bcrypt_test.rb +0 -16
  105. data/test/crypto_provider_test/scrypt_test.rb +0 -16
  106. data/test/crypto_provider_test/sha1_test.rb +0 -25
  107. data/test/crypto_provider_test/sha256_test.rb +0 -16
  108. data/test/crypto_provider_test/sha512_test.rb +0 -16
  109. data/test/crypto_provider_test/wordpress_test.rb +0 -26
  110. data/test/fixtures/companies.yml +0 -5
  111. data/test/fixtures/employees.yml +0 -17
  112. data/test/fixtures/projects.yml +0 -3
  113. data/test/fixtures/users.yml +0 -41
  114. data/test/i18n/lol.yml +0 -4
  115. data/test/i18n_test.rb +0 -35
  116. data/test/libs/affiliate.rb +0 -9
  117. data/test/libs/company.rb +0 -8
  118. data/test/libs/employee.rb +0 -9
  119. data/test/libs/employee_session.rb +0 -4
  120. data/test/libs/ldaper.rb +0 -5
  121. data/test/libs/project.rb +0 -5
  122. data/test/libs/user.rb +0 -9
  123. data/test/libs/user_session.rb +0 -27
  124. data/test/random_test.rb +0 -15
  125. data/test/session_test/activation_test.rb +0 -45
  126. data/test/session_test/active_record_trickery_test.rb +0 -78
  127. data/test/session_test/brute_force_protection_test.rb +0 -110
  128. data/test/session_test/callbacks_test.rb +0 -42
  129. data/test/session_test/cookies_test.rb +0 -226
  130. data/test/session_test/credentials_test.rb +0 -0
  131. data/test/session_test/existence_test.rb +0 -88
  132. data/test/session_test/foundation_test.rb +0 -24
  133. data/test/session_test/http_auth_test.rb +0 -60
  134. data/test/session_test/id_test.rb +0 -19
  135. data/test/session_test/klass_test.rb +0 -42
  136. data/test/session_test/magic_columns_test.rb +0 -62
  137. data/test/session_test/magic_states_test.rb +0 -60
  138. data/test/session_test/params_test.rb +0 -61
  139. data/test/session_test/password_test.rb +0 -107
  140. data/test/session_test/perishability_test.rb +0 -17
  141. data/test/session_test/persistence_test.rb +0 -35
  142. data/test/session_test/scopes_test.rb +0 -68
  143. data/test/session_test/session_test.rb +0 -80
  144. data/test/session_test/timeout_test.rb +0 -84
  145. data/test/session_test/unauthorized_record_test.rb +0 -15
  146. data/test/session_test/validation_test.rb +0 -25
  147. data/test/test_helper.rb +0 -272
@@ -1,82 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Authlogic tries to check the state of the record before creating the session. If
4
- # your record responds to the following methods and any of them return false,
5
- # validation will fail:
6
- #
7
- # Method name Description
8
- # active? Is the record marked as active?
9
- # approved? Has the record been approved?
10
- # confirmed? Has the record been confirmed?
11
- #
12
- # Authlogic does nothing to define these methods for you, its up to you to define what
13
- # they mean. If your object responds to these methods Authlogic will use them,
14
- # otherwise they are ignored.
15
- #
16
- # What's neat about this is that these are checked upon any type of login. When
17
- # logging in explicitly, by cookie, session, or basic http auth. So if you mark a user
18
- # inactive in the middle of their session they wont be logged back in next time they
19
- # refresh the page. Giving you complete control.
20
- #
21
- # Need Authlogic to check your own "state"? No problem, check out the hooks section
22
- # below. Add in a before_validation to do your own checking. The sky is the limit.
23
- module MagicStates
24
- def self.included(klass)
25
- klass.class_eval do
26
- extend Config
27
- include InstanceMethods
28
- validate :validate_magic_states, unless: :disable_magic_states?
29
- end
30
- end
31
-
32
- # Configuration for the magic states feature.
33
- module Config
34
- # Set this to true if you want to disable the checking of active?, approved?, and
35
- # confirmed? on your record. This is more or less of a convenience feature, since
36
- # 99% of the time if those methods exist and return false you will not want the
37
- # user logging in. You could easily accomplish this same thing with a
38
- # before_validation method or other callbacks.
39
- #
40
- # * <tt>Default:</tt> false
41
- # * <tt>Accepts:</tt> Boolean
42
- def disable_magic_states(value = nil)
43
- rw_config(:disable_magic_states, value, false)
44
- end
45
- alias_method :disable_magic_states=, :disable_magic_states
46
- end
47
-
48
- # The methods available for an Authlogic::Session::Base object that make up the
49
- # magic states feature.
50
- module InstanceMethods
51
- private
52
-
53
- def disable_magic_states?
54
- self.class.disable_magic_states == true
55
- end
56
-
57
- # @api private
58
- def required_magic_states_for(record)
59
- %i[active approved confirmed].select { |state|
60
- record.respond_to?("#{state}?")
61
- }
62
- end
63
-
64
- def validate_magic_states
65
- return true if attempted_record.nil?
66
- required_magic_states_for(attempted_record).each do |required_status|
67
- next if attempted_record.send("#{required_status}?")
68
- errors.add(
69
- :base,
70
- I18n.t(
71
- "error_messages.not_#{required_status}",
72
- default: "Your account is not #{required_status}"
73
- )
74
- )
75
- return false
76
- end
77
- true
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,130 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # This module is responsible for authenticating the user via params, which ultimately
4
- # allows the user to log in using a URL like the following:
5
- #
6
- # https://www.domain.com?user_credentials=4LiXF7FiGUppIPubBPey
7
- #
8
- # Notice the token in the URL, this is a single access token. A single access token is
9
- # used for single access only, it is not persisted. Meaning the user provides it,
10
- # Authlogic grants them access, and that's it. If they want access again they need to
11
- # provide the token again. Authlogic will *NEVER* try to persist the session after
12
- # authenticating through this method.
13
- #
14
- # For added security, this token is *ONLY* allowed for RSS and ATOM requests. You can
15
- # change this with the configuration. You can also define if it is allowed dynamically
16
- # by defining a single_access_allowed? method in your controller. For example:
17
- #
18
- # class UsersController < ApplicationController
19
- # private
20
- # def single_access_allowed?
21
- # action_name == "index"
22
- # end
23
- #
24
- # Also, by default, this token is permanent. Meaning if the user changes their
25
- # password, this token will remain the same. It will only change when it is explicitly
26
- # reset.
27
- #
28
- # You can modify all of this behavior with the Config sub module.
29
- module Params
30
- def self.included(klass)
31
- klass.class_eval do
32
- extend Config
33
- include InstanceMethods
34
- attr_accessor :single_access
35
- persist :persist_by_params
36
- end
37
- end
38
-
39
- # Configuration for the params / single access feature.
40
- module Config
41
- # Works exactly like cookie_key, but for params. So a user can login via
42
- # params just like a cookie or a session. Your URL would look like:
43
- #
44
- # http://www.domain.com?user_credentials=my_single_access_key
45
- #
46
- # You can change the "user_credentials" key above with this
47
- # configuration option. Keep in mind, just like cookie_key, if you
48
- # supply an id the id will be appended to the front. Check out
49
- # cookie_key for more details. Also checkout the "Single Access /
50
- # Private Feeds Access" section in the README.
51
- #
52
- # * <tt>Default:</tt> cookie_key
53
- # * <tt>Accepts:</tt> String
54
- def params_key(value = nil)
55
- rw_config(:params_key, value, cookie_key)
56
- end
57
- alias_method :params_key=, :params_key
58
-
59
- # Authentication is allowed via a single access token, but maybe this is
60
- # something you don't want for your application as a whole. Maybe this
61
- # is something you only want for specific request types. Specify a list
62
- # of allowed request types and single access authentication will only be
63
- # allowed for the ones you specify.
64
- #
65
- # * <tt>Default:</tt> ["application/rss+xml", "application/atom+xml"]
66
- # * <tt>Accepts:</tt> String of a request type, or :all or :any to
67
- # allow single access authentication for any and all request types
68
- def single_access_allowed_request_types(value = nil)
69
- rw_config(
70
- :single_access_allowed_request_types,
71
- value,
72
- ["application/rss+xml", "application/atom+xml"]
73
- )
74
- end
75
- alias_method :single_access_allowed_request_types=, :single_access_allowed_request_types
76
- end
77
-
78
- # The methods available for an Authlogic::Session::Base object that make
79
- # up the params / single access feature.
80
- module InstanceMethods
81
- private
82
-
83
- def persist_by_params
84
- return false unless params_enabled?
85
- self.unauthorized_record = search_for_record(
86
- "find_by_single_access_token",
87
- params_credentials
88
- )
89
- self.single_access = valid?
90
- end
91
-
92
- def params_enabled?
93
- if !params_credentials || !klass.column_names.include?("single_access_token")
94
- return false
95
- end
96
- if controller.responds_to_single_access_allowed?
97
- return controller.single_access_allowed?
98
- end
99
- params_enabled_by_allowed_request_types?
100
- end
101
-
102
- def params_enabled_by_allowed_request_types?
103
- case single_access_allowed_request_types
104
- when Array
105
- single_access_allowed_request_types.include?(controller.request_content_type) ||
106
- single_access_allowed_request_types.include?(:all)
107
- else
108
- %i[all any].include?(single_access_allowed_request_types)
109
- end
110
- end
111
-
112
- def params_key
113
- build_key(self.class.params_key)
114
- end
115
-
116
- def single_access?
117
- single_access == true
118
- end
119
-
120
- def single_access_allowed_request_types
121
- self.class.single_access_allowed_request_types
122
- end
123
-
124
- def params_credentials
125
- controller.params[params_key]
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,318 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Handles authenticating via a traditional username and password.
4
- module Password
5
- def self.included(klass)
6
- klass.class_eval do
7
- extend Config
8
- include InstanceMethods
9
- validate :validate_by_password, if: :authenticating_with_password?
10
-
11
- class << self
12
- attr_accessor :configured_password_methods
13
- end
14
- end
15
- end
16
-
17
- # Password configuration
18
- module Config
19
- # Authlogic tries to validate the credentials passed to it. One part of
20
- # validation is actually finding the user and making sure it exists.
21
- # What method it uses the do this is up to you.
22
- #
23
- # Let's say you have a UserSession that is authenticating a User. By
24
- # default UserSession will call User.find_by_login(login). You can
25
- # change what method UserSession calls by specifying it here. Then in
26
- # your User model you can make that method do anything you want, giving
27
- # you complete control of how users are found by the UserSession.
28
- #
29
- # Let's take an example: You want to allow users to login by username or
30
- # email. Set this to the name of the class method that does this in the
31
- # User model. Let's call it "find_by_username_or_email"
32
- #
33
- # class User < ActiveRecord::Base
34
- # def self.find_by_username_or_email(login)
35
- # find_by_username(login) || find_by_email(login)
36
- # end
37
- # end
38
- #
39
- # Now just specify the name of this method for this configuration option
40
- # and you are all set. You can do anything you want here. Maybe you
41
- # allow users to have multiple logins and you want to search a has_many
42
- # relationship, etc. The sky is the limit.
43
- #
44
- # * <tt>Default:</tt> "find_by_smart_case_login_field"
45
- # * <tt>Accepts:</tt> Symbol or String
46
- def find_by_login_method(value = nil)
47
- rw_config(:find_by_login_method, value, "find_by_smart_case_login_field")
48
- end
49
- alias_method :find_by_login_method=, :find_by_login_method
50
-
51
- # The text used to identify credentials (username/password) combination
52
- # when a bad login attempt occurs. When you show error messages for a
53
- # bad login, it's considered good security practice to hide which field
54
- # the user has entered incorrectly (the login field or the password
55
- # field). For a full explanation, see
56
- # http://www.gnucitizen.org/blog/username-enumeration-vulnerabilities/
57
- #
58
- # Example of use:
59
- #
60
- # class UserSession < Authlogic::Session::Base
61
- # generalize_credentials_error_messages true
62
- # end
63
- #
64
- # This would make the error message for bad logins and bad passwords
65
- # look identical:
66
- #
67
- # Login/Password combination is not valid
68
- #
69
- # Alternatively you may use a custom message:
70
- #
71
- # class UserSession < AuthLogic::Session::Base
72
- # generalize_credentials_error_messages "Your login information is invalid"
73
- # end
74
- #
75
- # This will instead show your custom error message when the UserSession is invalid.
76
- #
77
- # The downside to enabling this is that is can be too vague for a user
78
- # that has a hard time remembering their username and password
79
- # combinations. It also disables the ability to to highlight the field
80
- # with the error when you use form_for.
81
- #
82
- # If you are developing an app where security is an extreme priority
83
- # (such as a financial application), then you should enable this.
84
- # Otherwise, leaving this off is fine.
85
- #
86
- # * <tt>Default</tt> false
87
- # * <tt>Accepts:</tt> Boolean
88
- def generalize_credentials_error_messages(value = nil)
89
- rw_config(:generalize_credentials_error_messages, value, false)
90
- end
91
- alias_method :generalize_credentials_error_messages=, :generalize_credentials_error_messages
92
-
93
- # The name of the method you want Authlogic to create for storing the
94
- # login / username. Keep in mind this is just for your
95
- # Authlogic::Session, if you want it can be something completely
96
- # different than the field in your model. So if you wanted people to
97
- # login with a field called "login" and then find users by email this is
98
- # completely doable. See the find_by_login_method configuration option
99
- # for more details.
100
- #
101
- # * <tt>Default:</tt> klass.login_field || klass.email_field
102
- # * <tt>Accepts:</tt> Symbol or String
103
- def login_field(value = nil)
104
- rw_config(:login_field, value, klass.login_field || klass.email_field)
105
- end
106
- alias_method :login_field=, :login_field
107
-
108
- # Works exactly like login_field, but for the password instead. Returns
109
- # :password if a login_field exists.
110
- #
111
- # * <tt>Default:</tt> :password
112
- # * <tt>Accepts:</tt> Symbol or String
113
- def password_field(value = nil)
114
- rw_config(:password_field, value, login_field && :password)
115
- end
116
- alias_method :password_field=, :password_field
117
-
118
- # The name of the method in your model used to verify the password. This
119
- # should be an instance method. It should also be prepared to accept a
120
- # raw password and a crytped password.
121
- #
122
- # * <tt>Default:</tt> "valid_password?" defined in acts_as_authentic/password.rb
123
- # * <tt>Accepts:</tt> Symbol or String
124
- def verify_password_method(value = nil)
125
- rw_config(:verify_password_method, value, "valid_password?")
126
- end
127
- alias_method :verify_password_method=, :verify_password_method
128
- end
129
-
130
- # Password related instance methods
131
- module InstanceMethods
132
- def initialize(*args)
133
- unless self.class.configured_password_methods
134
- configure_password_methods
135
- self.class.configured_password_methods = true
136
- end
137
- instance_variable_set("@#{password_field}", nil)
138
- super
139
- end
140
-
141
- # Returns the login_field / password_field credentials combination in
142
- # hash form.
143
- def credentials
144
- if authenticating_with_password?
145
- details = {}
146
- details[login_field.to_sym] = send(login_field)
147
- details[password_field.to_sym] = "<protected>"
148
- details
149
- else
150
- super
151
- end
152
- end
153
-
154
- # Accepts the login_field / password_field credentials combination in
155
- # hash form.
156
- #
157
- # You must pass an actual Hash, `ActionController::Parameters` is
158
- # specifically not allowed.
159
- #
160
- # See `Authlogic::Session::Foundation#credentials=` for an overview of
161
- # all method signatures.
162
- def credentials=(value)
163
- super
164
- values = Array.wrap(value)
165
- if values.first.is_a?(Hash)
166
- sliced = values
167
- .first
168
- .with_indifferent_access
169
- .slice(login_field, password_field)
170
- sliced.each do |field, val|
171
- next if val.blank?
172
- send("#{field}=", val)
173
- end
174
- end
175
- end
176
-
177
- def invalid_password?
178
- invalid_password == true
179
- end
180
-
181
- private
182
-
183
- def add_invalid_password_error
184
- if generalize_credentials_error_messages?
185
- add_general_credentials_error
186
- else
187
- errors.add(
188
- password_field,
189
- I18n.t("error_messages.password_invalid", default: "is not valid")
190
- )
191
- end
192
- end
193
-
194
- def add_login_not_found_error
195
- if generalize_credentials_error_messages?
196
- add_general_credentials_error
197
- else
198
- errors.add(
199
- login_field,
200
- I18n.t("error_messages.login_not_found", default: "is not valid")
201
- )
202
- end
203
- end
204
-
205
- def authenticating_with_password?
206
- login_field && (!send(login_field).nil? || !send("protected_#{password_field}").nil?)
207
- end
208
-
209
- def configure_password_methods
210
- define_login_field_methods
211
- define_password_field_methods
212
- end
213
-
214
- def define_login_field_methods
215
- return unless login_field
216
- self.class.send(:attr_writer, login_field) unless respond_to?("#{login_field}=")
217
- self.class.send(:attr_reader, login_field) unless respond_to?(login_field)
218
- end
219
-
220
- def define_password_field_methods
221
- return unless password_field
222
- self.class.send(:attr_writer, password_field) unless respond_to?("#{password_field}=")
223
- self.class.send(:define_method, password_field) {} unless respond_to?(password_field)
224
-
225
- # The password should not be accessible publicly. This way forms
226
- # using form_for don't fill the password with the attempted
227
- # password. To prevent this we just create this method that is
228
- # private.
229
- self.class.class_eval(
230
- <<-EOS, __FILE__, __LINE__ + 1
231
- private
232
- def protected_#{password_field}
233
- @#{password_field}
234
- end
235
- EOS
236
- )
237
- end
238
-
239
- # In keeping with the metaphor of ActiveRecord, verification of the
240
- # password is referred to as a "validation".
241
- def validate_by_password
242
- self.invalid_password = false
243
- validate_by_password__blank_fields
244
- return if errors.count > 0
245
- self.attempted_record = search_for_record(find_by_login_method, send(login_field))
246
- if attempted_record.blank?
247
- add_login_not_found_error
248
- return
249
- end
250
- validate_by_password__invalid_password
251
- end
252
-
253
- def validate_by_password__blank_fields
254
- if send(login_field).blank?
255
- errors.add(
256
- login_field,
257
- I18n.t("error_messages.login_blank", default: "cannot be blank")
258
- )
259
- end
260
- if send("protected_#{password_field}").blank?
261
- errors.add(
262
- password_field,
263
- I18n.t("error_messages.password_blank", default: "cannot be blank")
264
- )
265
- end
266
- end
267
-
268
- # Verify the password, usually using `valid_password?` in
269
- # `acts_as_authentic/password.rb`. If it cannot be verified, we
270
- # refer to it as "invalid".
271
- def validate_by_password__invalid_password
272
- unless attempted_record.send(
273
- verify_password_method,
274
- send("protected_#{password_field}")
275
- )
276
- self.invalid_password = true
277
- add_invalid_password_error
278
- end
279
- end
280
-
281
- attr_accessor :invalid_password
282
-
283
- def find_by_login_method
284
- self.class.find_by_login_method
285
- end
286
-
287
- def login_field
288
- self.class.login_field
289
- end
290
-
291
- def add_general_credentials_error
292
- error_message =
293
- if self.class.generalize_credentials_error_messages.is_a? String
294
- self.class.generalize_credentials_error_messages
295
- else
296
- "#{login_field.to_s.humanize}/Password combination is not valid"
297
- end
298
- errors.add(
299
- :base,
300
- I18n.t("error_messages.general_credentials_error", default: error_message)
301
- )
302
- end
303
-
304
- def generalize_credentials_error_messages?
305
- self.class.generalize_credentials_error_messages
306
- end
307
-
308
- def password_field
309
- self.class.password_field
310
- end
311
-
312
- def verify_password_method
313
- self.class.verify_password_method
314
- end
315
- end
316
- end
317
- end
318
- end