authlogic 3.8.0 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  3. data/.github/ISSUE_TEMPLATE/feature_proposal.md +32 -0
  4. data/.github/triage.md +86 -0
  5. data/.gitignore +4 -3
  6. data/.rubocop.yml +109 -9
  7. data/.rubocop_todo.yml +38 -355
  8. data/.travis.yml +11 -35
  9. data/CHANGELOG.md +345 -2
  10. data/CONTRIBUTING.md +45 -14
  11. data/Gemfile +3 -2
  12. data/README.md +244 -90
  13. data/Rakefile +10 -10
  14. data/UPGRADING.md +22 -0
  15. data/authlogic.gemspec +34 -21
  16. data/doc/use_normal_rails_validation.md +82 -0
  17. data/gemfiles/Gemfile.rails-4.2.x +6 -0
  18. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.1.x +2 -2
  19. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.2.x +2 -2
  20. data/lib/authlogic/acts_as_authentic/base.rb +36 -24
  21. data/lib/authlogic/acts_as_authentic/email.rb +65 -31
  22. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +14 -9
  23. data/lib/authlogic/acts_as_authentic/login.rb +61 -45
  24. data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
  25. data/lib/authlogic/acts_as_authentic/password.rb +267 -146
  26. data/lib/authlogic/acts_as_authentic/perishable_token.rb +24 -19
  27. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -15
  28. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  29. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +50 -14
  30. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +88 -60
  31. data/lib/authlogic/acts_as_authentic/single_access_token.rb +23 -11
  32. data/lib/authlogic/acts_as_authentic/validations_scope.rb +9 -6
  33. data/lib/authlogic/authenticates_many/association.rb +7 -7
  34. data/lib/authlogic/authenticates_many/base.rb +37 -21
  35. data/lib/authlogic/config.rb +21 -10
  36. data/lib/authlogic/controller_adapters/abstract_adapter.rb +38 -11
  37. data/lib/authlogic/controller_adapters/rack_adapter.rb +9 -5
  38. data/lib/authlogic/controller_adapters/rails_adapter.rb +12 -7
  39. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +2 -2
  40. data/lib/authlogic/crypto_providers/aes256.rb +37 -32
  41. data/lib/authlogic/crypto_providers/bcrypt.rb +21 -15
  42. data/lib/authlogic/crypto_providers/md5.rb +4 -2
  43. data/lib/authlogic/crypto_providers/scrypt.rb +22 -17
  44. data/lib/authlogic/crypto_providers/sha1.rb +11 -5
  45. data/lib/authlogic/crypto_providers/sha256.rb +13 -9
  46. data/lib/authlogic/crypto_providers/sha512.rb +0 -21
  47. data/lib/authlogic/crypto_providers/wordpress.rb +32 -3
  48. data/lib/authlogic/crypto_providers.rb +91 -0
  49. data/lib/authlogic/i18n.rb +26 -19
  50. data/lib/authlogic/random.rb +10 -28
  51. data/lib/authlogic/regex.rb +59 -28
  52. data/lib/authlogic/session/activation.rb +10 -7
  53. data/lib/authlogic/session/active_record_trickery.rb +13 -9
  54. data/lib/authlogic/session/base.rb +15 -4
  55. data/lib/authlogic/session/brute_force_protection.rb +40 -33
  56. data/lib/authlogic/session/callbacks.rb +94 -46
  57. data/lib/authlogic/session/cookies.rb +130 -45
  58. data/lib/authlogic/session/existence.rb +21 -11
  59. data/lib/authlogic/session/foundation.rb +64 -14
  60. data/lib/authlogic/session/http_auth.rb +35 -28
  61. data/lib/authlogic/session/id.rb +9 -4
  62. data/lib/authlogic/session/klass.rb +15 -12
  63. data/lib/authlogic/session/magic_columns.rb +58 -55
  64. data/lib/authlogic/session/magic_states.rb +25 -19
  65. data/lib/authlogic/session/params.rb +42 -28
  66. data/lib/authlogic/session/password.rb +130 -120
  67. data/lib/authlogic/session/perishable_token.rb +5 -4
  68. data/lib/authlogic/session/persistence.rb +18 -12
  69. data/lib/authlogic/session/priority_record.rb +15 -12
  70. data/lib/authlogic/session/scopes.rb +51 -32
  71. data/lib/authlogic/session/session.rb +38 -28
  72. data/lib/authlogic/session/timeout.rb +13 -13
  73. data/lib/authlogic/session/unauthorized_record.rb +18 -13
  74. data/lib/authlogic/session/validation.rb +9 -9
  75. data/lib/authlogic/test_case/mock_controller.rb +5 -4
  76. data/lib/authlogic/test_case/mock_cookie_jar.rb +47 -3
  77. data/lib/authlogic/test_case/mock_request.rb +6 -3
  78. data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
  79. data/lib/authlogic/test_case.rb +70 -2
  80. data/lib/authlogic/version.rb +21 -0
  81. data/lib/authlogic.rb +51 -49
  82. data/test/acts_as_authentic_test/base_test.rb +3 -1
  83. data/test/acts_as_authentic_test/email_test.rb +43 -42
  84. data/test/acts_as_authentic_test/logged_in_status_test.rb +6 -4
  85. data/test/acts_as_authentic_test/login_test.rb +77 -80
  86. data/test/acts_as_authentic_test/magic_columns_test.rb +3 -1
  87. data/test/acts_as_authentic_test/password_test.rb +51 -37
  88. data/test/acts_as_authentic_test/perishable_token_test.rb +13 -5
  89. data/test/acts_as_authentic_test/persistence_token_test.rb +7 -1
  90. data/test/acts_as_authentic_test/restful_authentication_test.rb +14 -3
  91. data/test/acts_as_authentic_test/session_maintenance_test.rb +69 -15
  92. data/test/acts_as_authentic_test/single_access_test.rb +3 -1
  93. data/test/adapter_test.rb +23 -0
  94. data/test/authenticates_many_test.rb +3 -1
  95. data/test/config_test.rb +11 -9
  96. data/test/crypto_provider_test/aes256_test.rb +3 -1
  97. data/test/crypto_provider_test/bcrypt_test.rb +3 -1
  98. data/test/crypto_provider_test/scrypt_test.rb +3 -1
  99. data/test/crypto_provider_test/sha1_test.rb +3 -1
  100. data/test/crypto_provider_test/sha256_test.rb +3 -1
  101. data/test/crypto_provider_test/sha512_test.rb +3 -1
  102. data/test/crypto_provider_test/wordpress_test.rb +26 -0
  103. data/test/fixtures/companies.yml +2 -2
  104. data/test/fixtures/employees.yml +1 -1
  105. data/test/i18n_test.rb +6 -4
  106. data/test/libs/affiliate.rb +2 -0
  107. data/test/libs/company.rb +4 -2
  108. data/test/libs/employee.rb +2 -0
  109. data/test/libs/employee_session.rb +2 -0
  110. data/test/libs/ldaper.rb +2 -0
  111. data/test/libs/project.rb +2 -0
  112. data/test/libs/user.rb +2 -0
  113. data/test/libs/user_session.rb +4 -2
  114. data/test/random_test.rb +10 -38
  115. data/test/session_test/activation_test.rb +3 -1
  116. data/test/session_test/active_record_trickery_test.rb +7 -4
  117. data/test/session_test/brute_force_protection_test.rb +11 -9
  118. data/test/session_test/callbacks_test.rb +12 -4
  119. data/test/session_test/cookies_test.rb +48 -5
  120. data/test/session_test/existence_test.rb +18 -5
  121. data/test/session_test/foundation_test.rb +19 -1
  122. data/test/session_test/http_auth_test.rb +11 -7
  123. data/test/session_test/id_test.rb +3 -1
  124. data/test/session_test/klass_test.rb +3 -1
  125. data/test/session_test/magic_columns_test.rb +13 -13
  126. data/test/session_test/magic_states_test.rb +3 -1
  127. data/test/session_test/params_test.rb +13 -5
  128. data/test/session_test/password_test.rb +10 -8
  129. data/test/session_test/perishability_test.rb +3 -1
  130. data/test/session_test/persistence_test.rb +4 -1
  131. data/test/session_test/scopes_test.rb +16 -8
  132. data/test/session_test/session_test.rb +6 -4
  133. data/test/session_test/timeout_test.rb +4 -2
  134. data/test/session_test/unauthorized_record_test.rb +4 -2
  135. data/test/session_test/validation_test.rb +3 -1
  136. data/test/test_helper.rb +84 -45
  137. metadata +87 -73
  138. data/.github/ISSUE_TEMPLATE.md +0 -13
  139. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  141. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  142. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  143. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
data/README.md CHANGED
@@ -1,14 +1,61 @@
1
1
  # Authlogic
2
2
 
3
- **Authlogic supports rails 3, 4 and 5. For rails 2, see the [rails2 branch](https://github.com/binarylogic/authlogic/tree/rails2).**
3
+ A clean, simple, and unobtrusive ruby authentication solution.
4
4
 
5
- [![Gem Version](https://badge.fury.io/rb/authlogic.png)](http://badge.fury.io/rb/authlogic)
6
- [![Build Status](https://travis-ci.org/binarylogic/authlogic.png?branch=master)](https://travis-ci.org/binarylogic/authlogic)
7
- [![Code Climate](https://codeclimate.com/github/binarylogic/authlogic.png)](https://codeclimate.com/github/binarylogic/authlogic)
5
+ [![Gem Version][5]][6] [![Build Status][1]][2] [![Code Climate][7]][8] [![Dependency Status][3]][4]
8
6
 
9
- Authlogic is a clean, simple, and unobtrusive ruby authentication solution.
7
+ ## Sponsors
10
8
 
11
- It introduces a new type of model. You can have as many as you want, and name them whatever you want, just like your other models. In this example, we want to authenticate with the User model, which is inferred by the name:
9
+ [![Timber Logging](http://res.cloudinary.com/timber/image/upload/v1490556810/pricing/sponsorship.png)](https://timber.io?utm_source=github&utm_medium=authlogic)
10
+
11
+ [Tail Authlogic users](https://timber.io/docs/app/console/tail-a-user) in your logs!
12
+
13
+ ## Documentation
14
+
15
+ | Version | Documentation |
16
+ | ----------- | ------------- |
17
+ | Unreleased | https://github.com/binarylogic/authlogic/blob/master/README.md |
18
+ | 4.5.0 | https://github.com/binarylogic/authlogic/blob/v4.5.0/README.md |
19
+ | 3.7.0 | https://github.com/binarylogic/authlogic/blob/v3.7.0/README.md |
20
+ | 2.1.11 | https://github.com/binarylogic/authlogic/blob/v2.1.11/README.rdoc |
21
+ | 1.4.3 | https://github.com/binarylogic/authlogic/blob/v1.4.3/README.rdoc |
22
+
23
+ ## Table of Contents
24
+
25
+ - [1. Introduction](#1-introduction)
26
+ - [1.a. Compatibility](#1a-compatibility)
27
+ - [1.b. Overview](#1b-overview)
28
+ - [1.c. Reference Documentation](#1c-reference-documentation)
29
+ - [2. Rails](#2-rails)
30
+ - [2.a. The users table](#2a-the-users-table)
31
+ - [2.b. Controller](#2b-controller)
32
+ - [2.c. View](#2c-view)
33
+ - [2.d. CSRF Protection](#2d-csrf-protection)
34
+ - [3. Testing](#3-testing)
35
+ - [4. Helpful links](#4-helpful-links)
36
+ - [5. Add-ons](#5-add-ons)
37
+ - [6. Internals](#6-internals)
38
+
39
+ ## 1. Introduction
40
+
41
+ ### 1.a. Compatibility
42
+
43
+ | Version | branch | ruby | activerecord |
44
+ | ------- | ------------ | -------- | ------------- |
45
+ | 4.4 | 4-4-stable | >= 2.3.0 | >= 4.2, < 5.3 |
46
+ | 4.3 | 4-3-stable | >= 2.3.0 | >= 4.2, < 5.3 |
47
+ | 4.2 | 4-2-stable | >= 2.2.0 | >= 4.2, < 5.3 |
48
+ | 3 | 3-stable | >= 1.9.3 | >= 3.2, < 5.2 |
49
+ | 2 | rails2 | >= 1.9.3 | ~> 2.3.0 |
50
+ | 1 | ? | ? | ? |
51
+
52
+ Under SemVer, [changes to dependencies][10] do not require a major release.
53
+
54
+ ### 1.b. Overview
55
+
56
+ Authlogic introduces a new type of model. You can have as many as you want, and
57
+ name them whatever you want, just like your other models. In this example, we
58
+ want to authenticate with our `User` model, which is inferred from the name:
12
59
 
13
60
  ```ruby
14
61
  class UserSession < Authlogic::Session::Base
@@ -44,7 +91,8 @@ You can also log out (i.e. **destroying** the session):
44
91
  session.destroy
45
92
  ```
46
93
 
47
- After a session has been created, you can persist it (i.e. **finding** the record) across requests. Thus keeping the user logged in:
94
+ After a session has been created, you can persist it (i.e. **finding** the
95
+ record) across requests. Thus keeping the user logged in:
48
96
 
49
97
  ``` ruby
50
98
  session = UserSession.find
@@ -53,16 +101,20 @@ session = UserSession.find
53
101
  To get all of the nice authentication functionality in your model just do this:
54
102
 
55
103
  ```ruby
56
- class User < ActiveRecord::Base
104
+ class User < ApplicationRecord
57
105
  acts_as_authentic do |c|
58
106
  c.my_config_option = my_value
59
107
  end # the configuration block is optional
60
108
  end
61
109
  ```
62
110
 
63
- This handles validations, etc. It is also "smart" in the sense that it if a login field is present it will use that to authenticate, if not it will look for an email field, etc. This is all configurable, but for 99% of cases that above is all you will need to do.
111
+ This handles validations, etc. It is also "smart" in the sense that it if a
112
+ login field is present it will use that to authenticate, if not it will look for
113
+ an email field, etc. This is all configurable, but for 99% of cases that above
114
+ is all you will need to do.
64
115
 
65
- You may specify how passwords are cryptographically hashed (or encrypted) by setting the Authlogic::CryptoProvider option:
116
+ You may specify how passwords are cryptographically hashed (or encrypted) by
117
+ setting the Authlogic::CryptoProvider option:
66
118
 
67
119
  ``` ruby
68
120
  c.crypto_provider = Authlogic::CryptoProviders::BCrypt
@@ -74,74 +126,64 @@ You may validate international email addresses by enabling the provided alternat
74
126
  c.validates_format_of_email_field_options = {:with => Authlogic::Regex.email_nonascii}
75
127
  ```
76
128
 
77
- Also, sessions are automatically maintained. You can switch this on and off with configuration, but the following will automatically log a user in after a successful registration:
129
+ Also, sessions are automatically maintained. You can switch this on and off with
130
+ configuration, but the following will automatically log a user in after a
131
+ successful registration:
78
132
 
79
133
  ``` ruby
80
134
  User.create(params[:user])
81
135
  ```
82
136
 
83
- This also updates the session when the user changes his/her password.
84
-
85
- Authlogic is very flexible, it has a strong public API and a plethora of hooks to allow you to modify behavior and extend it. Check out the helpful links below to dig deeper.
86
-
87
- ## Upgrading to Authlogic 3.4.0
88
-
89
- In version 3.4.0, the default crypto_provider was changed from *Sha512* to *SCrypt*.
90
-
91
- If you never set a crypto_provider and are upgrading, your passwords will break unless you set the original:
137
+ You can switch this on and off with the following configuration:
92
138
 
93
- ``` ruby
94
- c.crypto_provider = Authlogic::CryptoProviders::Sha512
139
+ ```ruby
140
+ class User < ApplicationRecord
141
+ acts_as_authentic do |c|
142
+ c.log_in_after_create = false
143
+ end # the configuration block is optional
144
+ end
95
145
  ```
96
146
 
97
- And if you want to automatically upgrade from *Sha512* to *SCrypt* as users login:
147
+ Authlogic also updates the session when the user changes his/her password. You can also switch this on and off with the following configuration:
98
148
 
99
149
  ```ruby
100
- c.transition_from_crypto_providers = [Authlogic::CryptoProviders::Sha512]
101
- c.crypto_provider = Authlogic::CryptoProviders::SCrypt
150
+ class User < ApplicationRecord
151
+ acts_as_authentic do |c|
152
+ c.log_in_after_password_change = false
153
+ end # the configuration block is optional
154
+ end
102
155
  ```
103
156
 
104
- ## Helpful links
105
-
106
- * <b>Documentation:</b> http://rdoc.info/projects/binarylogic/authlogic
107
- * <b>Repository:</b> http://github.com/binarylogic/authlogic/tree/master
108
- * <b>Railscasts Screencast:</b> http://railscasts.com/episodes/160-authlogic
109
- * <b>Example repository with tutorial in README:</b> http://github.com/binarylogic/authlogic_example/tree/master
110
- * <b>Tutorial: Reset passwords with Authlogic the RESTful way:</b> http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic
111
- * <b>Tutorial</b>: Rails Authentication with Authlogic http://www.sitepoint.com/rails-authentication-with-authlogic
112
- * <b>Issues:</b> http://github.com/binarylogic/authlogic/issues
113
-
114
- ## Authlogic "add ons"
115
-
116
- * <b>Authlogic OpenID addon:</b> http://github.com/binarylogic/authlogic_openid
117
- * <b>Authlogic LDAP addon:</b> http://github.com/binarylogic/authlogic_ldap
118
- * <b>Authlogic Facebook Connect:</b> http://github.com/kalasjocke/authlogic_facebook_connect
119
- * <b>Authlogic Facebook Connect (New JS API):</b> http://github.com/studybyte/authlogic_facebook_connect
120
- * <b>Authlogic Facebook Shim</b> http://github.com/james2m/authlogic_facebook_shim
121
- * <b>Authlogic OAuth (Twitter):</b> http://github.com/jrallison/authlogic_oauth
122
- * <b>Authlogic Oauth and OpenID:</b> http://github.com/viatropos/authlogic-connect
123
- * <b>Authlogic PAM:</b> http://github.com/nbudin/authlogic_pam
124
- * <b>Authlogic x509:</b> http://github.com/auth-scc/authlogic_x509
157
+ Authlogic is very flexible, it has a strong public API and a plethora of hooks
158
+ to allow you to modify behavior and extend it. Check out the helpful links below
159
+ to dig deeper.
125
160
 
126
- If you create one of your own, please let me know about it so I can add it to this list. Or just fork the project, add your link, and send me a pull request.
161
+ ### 1.c. Reference Documentation
127
162
 
128
- ## Documentation explanation
163
+ This README is just an introduction, but we also have [reference
164
+ documentation](http://www.rubydoc.info/github/binarylogic/authlogic).
129
165
 
130
- You can find anything you want about Authlogic in the [documentation](http://rdoc.info/projects/binarylogic/authlogic), all that you need to do is understand the basic design behind it.
166
+ **To use the reference documentation, you must understand how Authlogic's
167
+ code is organized.** There are 2 models, your Authlogic model and your
168
+ ActiveRecord model:
131
169
 
132
- That being said, there are 2 models involved during authentication. Your Authlogic model and your ActiveRecord model:
170
+ 1. **Authlogic::Session**, your session models that
171
+ extend `Authlogic::Session::Base`.
172
+ 2. **Authlogic::ActsAsAuthentic**, which adds in functionality to your
173
+ ActiveRecord model when you call `acts_as_authentic`.
133
174
 
134
- 1. <b>Authlogic::Session</b>, your session models that extend Authlogic::Session::Base.
135
- 2. <b>Authlogic::ActsAsAuthentic</b>, which adds in functionality to your ActiveRecord model when you call acts_as_authentic.
175
+ Each of the above has various modules that are organized by topic: passwords,
176
+ cookies, etc. For example, if you want to timeout users after a certain period
177
+ of inactivity, you would look in `Authlogic::Session::Timeout`.
136
178
 
137
- Each of the above has its various sub modules that contain common logic. The sub modules are responsible for including *everything* related to it: configuration, class methods, instance methods, etc.
179
+ ## 2. Rails
138
180
 
139
- For example, if you want to timeout users after a certain period of inactivity, you would look in <b>Authlogic::Session::Timeout</b>. To help you out, I listed the following publicly relevant modules with short descriptions. For the sake of brevity, there are more modules than listed here, the ones not listed are more for internal use, but you can easily read up on them in the [documentation](http://rdoc.info/projects/binarylogic/authlogic).
181
+ Let's walk through a typical rails setup.
140
182
 
141
- ## Example migration
183
+ ### 2.a. The users table
142
184
 
143
185
  If you want to enable all the features of Authlogic, a migration to create a
144
- +User+ model, for example, might look like this:
186
+ `User` model might look like this:
145
187
 
146
188
  ``` ruby
147
189
  class CreateUser < ActiveRecord::Migration
@@ -156,12 +198,15 @@ class CreateUser < ActiveRecord::Migration
156
198
 
157
199
  # Authlogic::ActsAsAuthentic::PersistenceToken
158
200
  t.string :persistence_token
201
+ t.index :persistence_token, unique: true
159
202
 
160
203
  # Authlogic::ActsAsAuthentic::SingleAccessToken
161
204
  t.string :single_access_token
205
+ t.index :single_access_token, unique: true
162
206
 
163
207
  # Authlogic::ActsAsAuthentic::PerishableToken
164
208
  t.string :perishable_token
209
+ t.index :perishable_token, unique: true
165
210
 
166
211
  # Authlogic::Session::MagicColumns
167
212
  t.integer :login_count, default: 0, null: false
@@ -183,15 +228,56 @@ class CreateUser < ActiveRecord::Migration
183
228
  end
184
229
  ```
185
230
 
186
- ## Quick Rails example
187
-
188
- What if creating sessions worked like an ORM library on the surface...
231
+ In the `User` model,
189
232
 
190
- ``` ruby
191
- UserSession.create(params[:user_session])
233
+ ```ruby
234
+ class User < ApplicationRecord
235
+ acts_as_authentic
236
+
237
+ # Validate email, login, and password as you see fit.
238
+ #
239
+ # Authlogic < 5 added these validation for you, making them a little awkward
240
+ # to change. In 4.4.0, those automatic validations were deprecated. See
241
+ # https://github.com/binarylogic/authlogic/blob/master/doc/use_normal_rails_validation.md
242
+ validates :email,
243
+ format: {
244
+ with: ::Authlogic::Regex::EMAIL,
245
+ message: "should look like an email address."
246
+ },
247
+ length: { maximum: 100 },
248
+ uniqueness: {
249
+ case_sensitive: false,
250
+ if: :email_changed?
251
+ }
252
+
253
+ validates :login,
254
+ format: {
255
+ with: ::Authlogic::Regex::LOGIN,
256
+ message: "should use only letters, numbers, spaces, and .-_@+ please."
257
+ },
258
+ length: { within: 3..100 },
259
+ uniqueness: {
260
+ case_sensitive: false,
261
+ if: :login_changed?
262
+ }
263
+
264
+ validates :password,
265
+ confirmation: { if: :require_password? },
266
+ length: {
267
+ minimum: 8,
268
+ if: :require_password?
269
+ }
270
+ validates :password_confirmation,
271
+ length: {
272
+ minimum: 8,
273
+ if: :require_password?
274
+ }
275
+ end
192
276
  ```
193
277
 
194
- What if your user sessions controller could look just like your other controllers...
278
+ ### 2.b. Controller
279
+
280
+ Your sessions controller will look just like your other controllers.
195
281
 
196
282
  ```ruby
197
283
  class UserSessionsController < ApplicationController
@@ -200,7 +286,7 @@ class UserSessionsController < ApplicationController
200
286
  end
201
287
 
202
288
  def create
203
- @user_session = UserSession.new(params[:user_session])
289
+ @user_session = UserSession.new(user_session_params)
204
290
  if @user_session.save
205
291
  redirect_to account_url
206
292
  else
@@ -212,10 +298,37 @@ class UserSessionsController < ApplicationController
212
298
  current_user_session.destroy
213
299
  redirect_to new_user_session_url
214
300
  end
301
+
302
+ private
303
+
304
+ def user_session_params
305
+ params.require(:user_session).permit(:email, :password, :remember_me)
306
+ end
215
307
  end
216
308
  ```
217
309
 
218
- As you can see, this fits nicely into the RESTful development pattern. What about the view...
310
+ As you can see, this fits nicely into the [conventional controller methods][9].
311
+
312
+ #### 2.b.1. Helper Methods
313
+
314
+ ```ruby
315
+ class ApplicationController
316
+ helper_method :current_user_session, :current_user
317
+
318
+ private
319
+ def current_user_session
320
+ return @current_user_session if defined?(@current_user_session)
321
+ @current_user_session = UserSession.find
322
+ end
323
+
324
+ def current_user
325
+ return @current_user if defined?(@current_user)
326
+ @current_user = current_user_session && current_user_session.user
327
+ end
328
+ end
329
+ ```
330
+
331
+ ### 2.c. View
219
332
 
220
333
  ```erb
221
334
  <%= form_for @user_session do |f| %>
@@ -239,32 +352,18 @@ As you can see, this fits nicely into the RESTful development pattern. What abou
239
352
  <% end %>
240
353
  ```
241
354
 
242
- Or how about persisting the session...
355
+ ### 2.d. CSRF Protection
243
356
 
244
- ```ruby
245
- class ApplicationController
246
- helper_method :current_user_session, :current_user
357
+ Because Authlogic introduces its own methods for storing user sessions, the CSRF
358
+ (Cross Site Request Forgery) protection that is built into Rails will not work
359
+ out of the box.
247
360
 
248
- private
249
- def current_user_session
250
- return @current_user_session if defined?(@current_user_session)
251
- @current_user_session = UserSession.find
252
- end
253
-
254
- def current_user
255
- return @current_user if defined?(@current_user)
256
- @current_user = current_user_session && current_user_session.user
257
- end
258
- end
259
- ```
361
+ No generally applicable mitigation by the authlogic library is possible, because
362
+ the instance variable you use to store a reference to the user session in `def
363
+ current_user_session` will not be known to authlogic.
260
364
 
261
- ## CSRF Protection
262
-
263
- Because Authlogic introduces its own methods for storing user sessions, the CSRF (Cross Site Request Forgery) protection that is built into Rails will not work out of the box.
264
-
265
- No generally applicable mitigation by the authlogic library is possible, because the instance variable you use to store a reference to the user session in `def current_user_session` will not be known to authlogic.
266
-
267
- You will need to override `ActionController::Base#handle_unverified_request` to do something appropriate to how your app handles user sessions, e.g.:
365
+ You will need to override `ActionController::Base#handle_unverified_request` to
366
+ do something appropriate to how your app handles user sessions, e.g.:
268
367
 
269
368
  ```ruby
270
369
  class ApplicationController < ActionController::Base
@@ -283,12 +382,67 @@ class ApplicationController < ActionController::Base
283
382
  end
284
383
  ```
285
384
 
286
- ## Testing
385
+ ### 2.e SameSite Cookie Attribute
386
+ The SameSite attribute tells browsers when and how to fire cookies in first- or third-party situations. SameSite is used by a variety of browsers to identify whether or not to allow a cookie to be accessed.
387
+
388
+ Up until recently, the standard default value when SameSite was not explicitly defined was to allow cookies in both first- and third-party contexts. However, starting with Chrome 80+, the SameSite attribute will not default to Lax behavior meaning cookies will only be permitted in first-party contexts.
389
+
390
+ Authlogic can allow you to explicitly set the value of SameSite to one of: Lax, Strict, or None. Note that when setting SameSite to None, the `secure` flag must also be set (secure is the default in Authlogic).
391
+
392
+ Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#SameSite
393
+
394
+ ## 3. Testing
287
395
 
288
396
  See [Authlogic::TestCase](https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/test_case.rb)
289
397
 
290
- ## Tell me quickly how Authlogic works
398
+ ## 4. Helpful links
291
399
 
292
- Interested in how all of this all works? Think about an ActiveRecord model. A database connection must be established before you can use it. In the case of Authlogic, a controller connection must be established before you can use it. It uses that controller connection to modify cookies, the current session, login with HTTP basic, etc. It connects to the controller through a before filter that is automatically set in your controller which lets Authlogic know about the current controller object. Then Authlogic leverages that to do everything, it's a pretty simple design. Nothing crazy going on, Authlogic is just leveraging the tools your framework provides in the controller object.
400
+ * <b>API Reference:</b> http://www.rubydoc.info/github/binarylogic/authlogic
401
+ * <b>Repository:</b> https://github.com/binarylogic/authlogic/tree/master
402
+ * <b>Railscasts Screencast:</b> http://railscasts.com/episodes/160-authlogic
403
+ * <b>Example repository with tutorial in README:</b> https://github.com/binarylogic/authlogic_example/tree/master
404
+ * <b>Tutorial</b>: Rails Authentication with Authlogic https://www.sitepoint.com/rails-authentication-with-authlogic
405
+ * <b>Issues:</b> https://github.com/binarylogic/authlogic/issues
406
+ * <b>Chrome is not logging out on browser close</b> https://productforums.google.com/forum/#!topic/chrome/9l-gKYIUg50/discussion
407
+
408
+ ## 5. Add-ons
409
+
410
+ * <b>Authlogic OpenID addon:</b> https://github.com/binarylogic/authlogic_openid
411
+ * <b>Authlogic LDAP addon:</b> https://github.com/binarylogic/authlogic_ldap
412
+ * <b>Authlogic Facebook Connect:</b> https://github.com/kalasjocke/authlogic-facebook-connect
413
+ * <b>Authlogic Facebook Connect (New JS API):</b> https://github.com/studybyte/authlogic_facebook_connect
414
+ * <b>Authlogic Facebook Shim</b> https://github.com/james2m/authlogic_facebook_shim
415
+ * <b>Authlogic OAuth (Twitter):</b> https://github.com/jrallison/authlogic_oauth
416
+ * <b>Authlogic Oauth and OpenID:</b> https://github.com/lancejpollard/authlogic-connect
417
+ * <b>Authlogic PAM:</b> https://github.com/nbudin/authlogic_pam
418
+ * <b>Authlogic x509:</b> https://github.com/auth-scc/authlogic_x509
419
+
420
+ If you create one of your own, please let us know about it so we can add it to
421
+ this list. Or just fork the project, add your link, and send us a pull request.
422
+
423
+ ## 6. Internals
424
+
425
+ Interested in how all of this all works? Think about an ActiveRecord model. A
426
+ database connection must be established before you can use it. In the case of
427
+ Authlogic, a controller connection must be established before you can use it. It
428
+ uses that controller connection to modify cookies, the current session, login
429
+ with HTTP basic, etc. It connects to the controller through a before filter that
430
+ is automatically set in your controller which lets Authlogic know about the
431
+ current controller object. Then Authlogic leverages that to do everything, it's
432
+ a pretty simple design. Nothing crazy going on, Authlogic is just leveraging the
433
+ tools your framework provides in the controller object.
434
+
435
+ ## Intellectual Property
293
436
 
294
437
  Copyright (c) 2012 Ben Johnson of Binary Logic, released under the MIT license
438
+
439
+ [1]: https://api.travis-ci.org/binarylogic/authlogic.svg?branch=master
440
+ [2]: https://travis-ci.org/binarylogic/authlogic
441
+ [3]: https://gemnasium.com/badges/github.com/binarylogic/authlogic.svg
442
+ [4]: https://gemnasium.com/binarylogic/authlogic
443
+ [5]: https://badge.fury.io/rb/authlogic.png
444
+ [6]: http://badge.fury.io/rb/authlogic
445
+ [7]: https://codeclimate.com/github/binarylogic/authlogic.png
446
+ [8]: https://codeclimate.com/github/binarylogic/authlogic
447
+ [9]: http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
448
+ [10]: https://semver.org/spec/v2.0.0.html#what-should-i-do-if-i-update-my-own-dependencies-without-changing-the-public-api
data/Rakefile CHANGED
@@ -1,21 +1,21 @@
1
- require 'rubygems'
2
- require 'bundler'
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+ require "bundler"
3
5
 
4
6
  Bundler.setup
5
7
 
6
- require 'rake/testtask'
8
+ require "rake/testtask"
7
9
  Rake::TestTask.new(:test) do |test|
8
- test.libs << 'test'
9
- test.pattern = 'test/**/*_test.rb'
10
+ test.libs << "test"
11
+ test.pattern = "test/**/*_test.rb"
10
12
  test.verbose = false
11
13
 
12
- # Set interpreter warning level to 1 (medium). Level 2 produces hundreds of warnings
13
- # about uninitialized instance variables.
14
- # TODO: Find a good way to deal with the level 2 warnings.
15
- test.ruby_opts += ["-W1"]
14
+ # Set interpreter warning level to 2 (verbose)
15
+ test.ruby_opts += ["-W2"]
16
16
  end
17
17
 
18
18
  require "rubocop/rake_task"
19
19
  RuboCop::RakeTask.new
20
20
 
21
- task :default => [:rubocop, :test]
21
+ task default: %i[rubocop test]
data/UPGRADING.md ADDED
@@ -0,0 +1,22 @@
1
+ # Upgrading Authlogic
2
+
3
+ Supplemental instructions to complement CHANGELOG.md.
4
+
5
+ ## 3.4.0
6
+
7
+ In version 3.4.0, released 2014-03-03, the default crypto_provider was changed
8
+ from *Sha512* to *SCrypt*.
9
+
10
+ If you never set a crypto_provider and are upgrading, your passwords will break
11
+ unless you specify `Sha512`.
12
+
13
+ ``` ruby
14
+ c.crypto_provider = Authlogic::CryptoProviders::Sha512
15
+ ```
16
+
17
+ And if you want to automatically upgrade from *Sha512* to *SCrypt* as users login:
18
+
19
+ ```ruby
20
+ c.transition_from_crypto_providers = [Authlogic::CryptoProviders::Sha512]
21
+ c.crypto_provider = Authlogic::CryptoProviders::SCrypt
22
+ ```
data/authlogic.gemspec CHANGED
@@ -1,27 +1,40 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
3
2
 
4
- Gem::Specification.new do |s|
5
- s.name = "authlogic"
6
- s.version = "3.8.0"
7
- s.platform = Gem::Platform::RUBY
8
- s.authors = ["Ben Johnson"]
9
- s.email = ["bjohnson@binarylogic.com"]
10
- s.homepage = "http://github.com/binarylogic/authlogic"
11
- s.summary = 'A clean, simple, and unobtrusive ruby authentication solution.'
3
+ require "English"
4
+ $LOAD_PATH.push File.expand_path("lib", __dir__)
5
+ require "authlogic/version"
12
6
 
13
- s.license = 'MIT'
7
+ ::Gem::Specification.new do |s|
8
+ s.name = "authlogic"
9
+ s.version = ::Authlogic.gem_version.to_s
10
+ s.platform = ::Gem::Platform::RUBY
11
+ s.authors = [
12
+ "Ben Johnson",
13
+ "Tieg Zaharia",
14
+ "Jared Beck"
15
+ ]
16
+ s.email = [
17
+ "bjohnson@binarylogic.com",
18
+ "tieg.zaharia@gmail.com",
19
+ "jared@jaredbeck.com"
20
+ ]
21
+ s.homepage = "http://github.com/binarylogic/authlogic"
22
+ s.summary = "A clean, simple, and unobtrusive ruby authentication solution."
23
+ s.license = "MIT"
14
24
 
15
- s.add_dependency 'activerecord', ['>= 3.2', '< 5.3']
16
- s.add_dependency 'activesupport', ['>= 3.2', '< 5.3']
17
- s.add_dependency 'request_store', '~> 1.0'
18
- s.add_dependency 'scrypt', '>= 1.2', '< 4.0'
19
- s.add_development_dependency 'bcrypt', '~> 3.1'
20
- s.add_development_dependency 'timecop', '~> 0.7'
21
- s.add_development_dependency 'rubocop', '~> 0.41.2'
25
+ s.required_ruby_version = ">= 2.3.0"
26
+ s.add_dependency "activerecord", [">= 4.2", "< 5.3"]
27
+ s.add_dependency "activesupport", [">= 4.2", "< 5.3"]
28
+ s.add_dependency "request_store", "~> 1.0"
29
+ s.add_dependency "scrypt", ">= 1.2", "< 4.0"
30
+ s.add_development_dependency "bcrypt", "~> 3.1"
31
+ s.add_development_dependency "byebug", "~> 10.0"
32
+ s.add_development_dependency "minitest-reporters", "~> 1.3"
33
+ s.add_development_dependency "rubocop", "~> 0.58.1"
34
+ s.add_development_dependency "timecop", "~> 0.7"
22
35
 
23
- s.files = `git ls-files`.split("\n")
24
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
36
+ s.files = `git ls-files`.split("\n")
37
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
38
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
26
39
  s.require_paths = ["lib"]
27
40
  end
@@ -0,0 +1,82 @@
1
+ # Use Normal ActiveRecord Validation
2
+
3
+ In Authlogic 4.4.0, [we deprecated][1] the features of Authlogic related to
4
+ validating email, login, and password. In 5.0.0 these features will be dropped.
5
+ Use normal ActiveRecord validations instead.
6
+
7
+ ## Instructions
8
+
9
+ First, disable the deprecated Authlogic validations:
10
+
11
+ acts_as_authentic do |c|
12
+ c.validate_email_field = false
13
+ c.validate_login_field = false
14
+ c.validate_password_field = false
15
+ end
16
+
17
+ Then, use normal ActiveRecord validations instead. For example, instead of
18
+ the Authlogic method validates_length_of_email_field_options, use
19
+
20
+ validates :email, length: { ... }
21
+
22
+ It might be a good idea to replace these one field at a time, ie. email,
23
+ then login, then password; one field per commit.
24
+
25
+ ## Default Values
26
+
27
+ The following validations represent the Authlogic < 5 defaults. Merge these
28
+ defaults with any settings you may have overwritten.
29
+
30
+ ```
31
+ validates :email,
32
+ format: {
33
+ with: ::Authlogic::Regex::EMAIL,
34
+ message: proc {
35
+ ::Authlogic::I18n.t(
36
+ "error_messages.email_invalid",
37
+ default: "should look like an email address."
38
+ )
39
+ }
40
+ },
41
+ length: { maximum: 100 },
42
+ uniqueness: {
43
+ case_sensitive: false,
44
+ if: :email_changed?
45
+ }
46
+
47
+ validates :login,
48
+ format: {
49
+ with: ::Authlogic::Regex::LOGIN,
50
+ message: proc {
51
+ ::Authlogic::I18n.t(
52
+ "error_messages.login_invalid",
53
+ default: "should use only letters, numbers, spaces, and .-_@+ please."
54
+ )
55
+ }
56
+ },
57
+ length: { within: 3..100 },
58
+ uniqueness: {
59
+ case_sensitive: false,
60
+ if: :login_changed?
61
+ }
62
+
63
+ validates :password,
64
+ confirmation: { if: :require_password? },
65
+ length: {
66
+ minimum: 8,
67
+ if: :require_password?
68
+ }
69
+ validates :password_confirmation,
70
+ length: {
71
+ minimum: 8,
72
+ if: :require_password?
73
+ }
74
+ ```
75
+
76
+ ## Motivation
77
+
78
+ The deprecated features save people some time in the begginning, when setting up
79
+ Authlogic. But, later in the life of a project, when these settings need to
80
+ change, it is obscure compared to normal ActiveRecord validations.
81
+
82
+ [1]: https://github.com/binarylogic/authlogic/pull/623
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+ gemspec :path => ".."
3
+
4
+ gem "activerecord", "~> 4.2.8.rc1"
5
+ gem "activesupport", "~> 4.2.8.rc1"
6
+ gem "sqlite3", "~> 1.3.6", platforms: :ruby