authlogic 4.4.2 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
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