authlogic 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of authlogic might be problematic. Click here for more details.

Files changed (34) hide show
  1. data/CHANGELOG.rdoc +7 -0
  2. data/Manifest +4 -4
  3. data/README.rdoc +49 -20
  4. data/Rakefile +0 -1
  5. data/authlogic.gemspec +9 -7
  6. data/lib/authlogic.rb +3 -3
  7. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb +35 -17
  8. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb +21 -17
  9. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb +75 -0
  10. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb +7 -7
  11. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb +1 -1
  12. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb +2 -2
  13. data/lib/authlogic/session/authenticates_many_association.rb +1 -0
  14. data/lib/authlogic/session/config.rb +4 -4
  15. data/lib/authlogic/session/cookies.rb +2 -2
  16. data/lib/authlogic/session/params.rb +2 -2
  17. data/lib/authlogic/session/perishability.rb +18 -0
  18. data/lib/authlogic/session/session.rb +2 -2
  19. data/lib/authlogic/version.rb +1 -1
  20. data/test/fixtures/employees.yml +2 -2
  21. data/test/fixtures/users.yml +3 -3
  22. data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb +8 -4
  23. data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb +5 -5
  24. data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb +41 -0
  25. data/test/session_tests/authenticates_many_association_test.rb +8 -0
  26. data/test/session_tests/base_test.rb +4 -4
  27. data/test/session_tests/cookies_test.rb +1 -1
  28. data/test/session_tests/{password_reset_test.rb → perishability_test.rb} +3 -3
  29. data/test/session_tests/session_test.rb +4 -4
  30. data/test/test_helper.rb +5 -5
  31. metadata +11 -11
  32. data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb +0 -73
  33. data/lib/authlogic/session/password_reset.rb +0 -17
  34. data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb +0 -40
@@ -1,3 +1,10 @@
1
+ == 1.2.1 released 2008-11-19
2
+
3
+ * Added build method to authenticates_many association to act like AR association collections.
4
+ * Added validation boolean configuration options for acts_as_authentic: validate_field, validate_login_field, validate_password_field, validate_email_field. This turns on and off validations for their respective fields.
5
+ * Renamed all password_reset_token terms to perishable_token, including configuration, etc. I still allow for the old configurations so this will not break compatibility, but perishable token is a better name and can be used for account confirmation as well as a password reset token, or anything else you want.
6
+ * Renamed all remember_token instances to persistence_token, the term "remember token" doesn't really make sense. I still allow for the old configuration, so this will not break backwards compatibility: persistence_token fits better and makes more sense.
7
+
1
8
  == 1.2.0 released 2008-11-16
2
9
 
3
10
  * Added check for database set up in acts_as_authentic to prevent errors during migrations.
data/Manifest CHANGED
@@ -8,7 +8,7 @@ lib/authlogic/crypto_providers/sha512.rb
8
8
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb
9
9
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb
10
10
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb
11
- lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb
11
+ lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb
12
12
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb
13
13
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb
14
14
  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb
@@ -22,7 +22,7 @@ lib/authlogic/session/config.rb
22
22
  lib/authlogic/session/cookies.rb
23
23
  lib/authlogic/session/errors.rb
24
24
  lib/authlogic/session/params.rb
25
- lib/authlogic/session/password_reset.rb
25
+ lib/authlogic/session/perishability.rb
26
26
  lib/authlogic/session/scopes.rb
27
27
  lib/authlogic/session/session.rb
28
28
  lib/authlogic/version.rb
@@ -44,7 +44,7 @@ test/libs/ordered_hash.rb
44
44
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
45
45
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb
46
46
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb
47
- test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb
47
+ test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb
48
48
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb
49
49
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb
50
50
  test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb
@@ -55,7 +55,7 @@ test/session_tests/base_test.rb
55
55
  test/session_tests/config_test.rb
56
56
  test/session_tests/cookies_test.rb
57
57
  test/session_tests/params_test.rb
58
- test/session_tests/password_reset_test.rb
58
+ test/session_tests/perishability_test.rb
59
59
  test/session_tests/scopes_test.rb
60
60
  test/session_tests/session_test.rb
61
61
  test/test_helper.rb
@@ -32,6 +32,7 @@ What if your user sessions controller could look just like your other controller
32
32
 
33
33
  def destroy
34
34
  current_user_session.destroy
35
+ redirect_to new_user_session_url
35
36
  end
36
37
  end
37
38
 
@@ -109,9 +110,9 @@ The user model needs to have the following columns. The names of these columns c
109
110
  t.string :login, :null => false
110
111
  t.string :crypted_password, :null => false
111
112
  t.string :password_salt, :null => false # not needed if you are encrypting your pw instead of using a hash algorithm.
112
- t.string :remember_token, :null => false
113
- t.string :single_access_token, :null => false # optional, see the single access section below.
114
- t.string :password_reset_token, :null => false # optional, see the password reset section below.
113
+ t.string :persistence_token, :null => false
114
+ t.string :single_access_token, :null => false # optional, see the tokens section below.
115
+ t.string :perishable_token, :null => false # optional, see the tokens section below.
115
116
  t.integer :login_count # optional, this is a "magic" column, see the magic columns section below
116
117
 
117
118
  === Set up your model
@@ -191,39 +192,67 @@ This will keep everything separate. The :secure session will store its info in a
191
192
 
192
193
  For more information on ids checkout Authlogic::Session::Base#id
193
194
 
194
- == Resetting passwords
195
+ == Tokens (persistence, resetting passwords, private feed access, etc.)
195
196
 
196
- You may have noticed in the helpful links section is a tutorial on resetting password with Authlogic. I'm not going to repeat myself here, but I will touch on the basics, if you want more information please see the tutorial.
197
+ To start, let me define tokens as Authlogic sees it. A token is a form of credentials that grants some type of access to their account. Depending on the type of access, a different type of token may be needed. Put simply, it's a way for the user to say "I am this person, let me proceed". What types of different access you ask? Here are just a few:
197
198
 
198
- Just add the following field to your database:
199
+ 1. Regular account access
200
+ 2. Access to reset their password
201
+ 3. Access to a private feed
202
+ 4. Access to confirm their account
199
203
 
200
- t.string :password_reset_token, :null => false
204
+ There could be many more depending on your application. What's great about Authlogic is that it doesn't care what you do or how you want to grant access to accounts. That's up to you and your application. Authlogic just cares about the type of tokens you need. Instead of giving you a token for each specific task, it gives you all of the necessary *types* of tokens, and you get to use them how you wish. It maintains the tokens and gives you all of the tools you need to use them. Just add the fields to your database and you are good to go.
201
205
 
202
- Authlogic will notice this field and take care of maintaining it for you. You should use the value of this field to verify your user before they reset their password. There is a finder method you can use to find users with this token, I highly recommend using this method, as it adds in extra security checks to verify the user. See Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::PasswordReset for more information.
206
+ Here are the 3 tokens in more detail:
203
207
 
204
- == Single Access / Private Feeds Access
208
+ === Persistence token
205
209
 
206
- Need to provide a single / one time access to an account where the session does NOT get persisted? Take a private feed for example, if everyone followed standards, basic http auth should work just fine, but since we live in a world where following standards is not a standard (\*cough\* Microsoft \*cough\*), the feed url needs to have some sort of "credentials" to log the user in and get their user specific feed items. This is easy, Authlogic has a nifty little feature for doing just this. All that you need to do is add the following field in your table:
210
+ This token is used to persist the user's session. This is the token that is stored in the session and the cookie, so that during each request the user stays logged in. What's unique about this token is that the first time it is used the value is stored in the session, thus persisting the session. This field is required and must be in your database.
211
+
212
+ === Single access token
213
+
214
+ This token is used for single access only, it is not persisted. Meaning the user provides it, Authlogic grants them access, and that's it. If they want access again they need to provide the token again. Authlogic will *NEVER* store this value in the session or a cookie. Also, for added security, by default this token is *ONLY* allowed for RSS and ATOM requests. Lastly, this token does *NOT* change with the password. Meaning if the user changes their password, this token will remain the same. You can change all of this with configuration (see Authlogic::Session::config), so if you don't like how this works by default, just set some simple configuration in your session.
215
+
216
+ This field is optional, if you want to use it just add the field to your database:
207
217
 
208
218
  t.string :single_access_token, :null => false
209
219
  # or call it feeds_token, feed_token, or whatever you want with configuration
210
220
 
211
- Authlogic will notice you have this and adjust accordingly. By default single_access_tokens can only be used to login for rss and atom request types.
221
+ This is great for private feed access. So your URL to that user's private feed could look something like:
222
+
223
+ http://www.mydomain.com/account/feed.rss?single_access_token=4LiXF7FiGUppIPubBPey
224
+
225
+ The single_access_token parameter name is configurable (see Authlogic::Session::Config), but if that parameter exists Authlogic will automatically use it to try and grant that user access. You don't have to do a thing: UserSession.find will take care of it just like it does for everything else.
226
+
227
+ For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::SingleAccess
228
+
229
+ === Perishable token
230
+
231
+ This token is used for temporary account access, hence the term "perishable". This token is constantly changing, it changes...
232
+
233
+ 1. In a before_validation in your model, so basically every time the record is saved
234
+ 2. Any time a new session is successfully saved (aka logged in)
235
+
236
+ This is perfect for <b>resetting passwords</b> or <b>confirming accounts</b>. You email them a url with this token in it, and then use this token to find the record and perform your action.
237
+
238
+ This field is optional, if you want to use it just add the field to your database:
239
+
240
+ t.string :perishable_token, :null => false
241
+ # or call it password_reset_token, pw_reset_token, activation_token, or whatever you want with configuration
212
242
 
213
- To tailor how this works, you have the following configuration options:
243
+ Finding the record with this token couldn't be easier, Authlogic provides a special finder method that you can use. I highly recommend using it as it adds extra security:
214
244
 
215
- Session configuration (Authlogic::Session::Config)
245
+ User.find_using_perishable_token(token)
246
+ User.find_using_perishable_token(token, 20.minutes)
216
247
 
217
- 1. params_key
218
- 2. single_access_allowed_request_types
219
- 3. single_access_token_field
248
+ That's all you need to do to locate the record. Here is what it does for extra security:
220
249
 
221
- Model configuration (Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Config)
250
+ 1. Ignores blank tokens all together. If a blank token is passed nil will be returned.
251
+ 2. It checks the age of the token, by default the threshold is 10 minutes, meaning if the token is older than 10 minutes, it is not valid and no record will be returned. You can change the default or just override it by passing the threshold as the second parameter. If you don't want a threshold at all, pass 0.
222
252
 
223
- 1. single_access_token_field:
224
- 2. change_single_access_token_with_password
253
+ For a detailed tutorial on how to reset password using this token see the helpful links section above.
225
254
 
226
- Please use this with care and make sure you warn your users that the URL you provide them is to remain private. Even if Billy 13 year old gets this URL and tries to log in, the only way he can login is through a GET or POST parameter with an rss or atom request. Billy can't create a cookie with this token and Billy wont have access to anything else on the site, unless you change the above configuration.
255
+ For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Perishability
227
256
 
228
257
  == Scoping
229
258
 
data/Rakefile CHANGED
@@ -11,5 +11,4 @@ Echoe.new 'authlogic' do |p|
11
11
  p.summary = "A clean, simple, and unobtrusive ruby authentication solution."
12
12
  p.url = "http://github.com/binarylogic/authlogic"
13
13
  p.dependencies = %w(activesupport)
14
- p.include_rakefile = true
15
14
  end
@@ -1,28 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = %q{authlogic}
3
- s.version = "1.2.0"
5
+ s.version = "1.2.1"
4
6
 
5
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
8
  s.authors = ["Ben Johnson of Binary Logic"]
7
- s.date = %q{2008-11-16}
9
+ s.date = %q{2008-11-19}
8
10
  s.description = %q{A clean, simple, and unobtrusive ruby authentication solution.}
9
11
  s.email = %q{bjohnson@binarylogic.com}
10
- s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "lib/authlogic/crypto_providers/sha512.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/password_reset.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "README.rdoc"]
11
- s.files = ["CHANGELOG.rdoc", "init.rb", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "lib/authlogic/crypto_providers/sha512.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/password_reset.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "shoulda_macros/authlogic.rb", "test/fixtures/companies.yml", "test/fixtures/employees.yml", "test/fixtures/projects.yml", "test/fixtures/users.yml", "test/libs/aes128_crypto_provider.rb", "test/libs/mock_controller.rb", "test/libs/mock_cookie_jar.rb", "test/libs/mock_request.rb", "test/libs/ordered_hash.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "test/session_tests/base_test.rb", "test/session_tests/config_test.rb", "test/session_tests/cookies_test.rb", "test/session_tests/params_test.rb", "test/session_tests/password_reset_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb", "authlogic.gemspec"]
12
+ s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "lib/authlogic/crypto_providers/sha512.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/perishability.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "README.rdoc"]
13
+ s.files = ["CHANGELOG.rdoc", "init.rb", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "lib/authlogic/crypto_providers/sha512.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/perishability.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "shoulda_macros/authlogic.rb", "test/fixtures/companies.yml", "test/fixtures/employees.yml", "test/fixtures/projects.yml", "test/fixtures/users.yml", "test/libs/aes128_crypto_provider.rb", "test/libs/mock_controller.rb", "test/libs/mock_cookie_jar.rb", "test/libs/mock_request.rb", "test/libs/ordered_hash.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "test/session_tests/base_test.rb", "test/session_tests/config_test.rb", "test/session_tests/cookies_test.rb", "test/session_tests/params_test.rb", "test/session_tests/perishability_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb", "authlogic.gemspec"]
12
14
  s.has_rdoc = true
13
15
  s.homepage = %q{http://github.com/binarylogic/authlogic}
14
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Authlogic", "--main", "README.rdoc"]
15
17
  s.require_paths = ["lib"]
16
18
  s.rubyforge_project = %q{authlogic}
17
- s.rubygems_version = %q{1.2.0}
19
+ s.rubygems_version = %q{1.3.1}
18
20
  s.summary = %q{A clean, simple, and unobtrusive ruby authentication solution.}
19
- s.test_files = ["test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "test/session_tests/base_test.rb", "test/session_tests/config_test.rb", "test/session_tests/cookies_test.rb", "test/session_tests/params_test.rb", "test/session_tests/password_reset_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb"]
21
+ s.test_files = ["test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "test/session_tests/base_test.rb", "test/session_tests/config_test.rb", "test/session_tests/cookies_test.rb", "test/session_tests/params_test.rb", "test/session_tests/perishability_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb"]
20
22
 
21
23
  if s.respond_to? :specification_version then
22
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
25
  s.specification_version = 2
24
26
 
25
- if current_version >= 3 then
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
28
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
27
29
  s.add_development_dependency(%q<echoe>, [">= 0"])
28
30
  else
@@ -13,7 +13,7 @@ if defined?(ActiveRecord)
13
13
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic"
14
14
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials"
15
15
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in"
16
- require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset"
16
+ require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability"
17
17
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence"
18
18
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance"
19
19
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access"
@@ -28,7 +28,7 @@ require File.dirname(__FILE__) + "/authlogic/session/config"
28
28
  require File.dirname(__FILE__) + "/authlogic/session/cookies"
29
29
  require File.dirname(__FILE__) + "/authlogic/session/errors"
30
30
  require File.dirname(__FILE__) + "/authlogic/session/params"
31
- require File.dirname(__FILE__) + "/authlogic/session/password_reset"
31
+ require File.dirname(__FILE__) + "/authlogic/session/perishability"
32
32
  require File.dirname(__FILE__) + "/authlogic/session/session"
33
33
  require File.dirname(__FILE__) + "/authlogic/session/scopes"
34
34
  require File.dirname(__FILE__) + "/authlogic/session/base"
@@ -40,7 +40,7 @@ module Authlogic
40
40
  include Callbacks
41
41
  include Cookies
42
42
  include Params
43
- include PasswordReset
43
+ include Perishability
44
44
  include Session
45
45
  include Scopes
46
46
  end
@@ -21,13 +21,19 @@ module Authlogic
21
21
  #
22
22
  # * <tt>crypto_provider</tt> - default: Authlogic::CryptoProviders::Sha512,
23
23
  # This is the class that provides your encryption. By default Authlogic provides its own crypto provider that uses Sha512 encrypton.
24
- #
24
+ #
25
+ # * <tt>validate_fields</tt> - default: true,
26
+ # Tells Authlogic if it should validate ANY of the fields: login_field, email_field, and password_field. If set to false, no validations will be set for any of these fields.
27
+ #
25
28
  # * <tt>login_field</tt> - default: :login, :username, or :email, depending on which column is present, if none are present defaults to :login
26
29
  # The name of the field used for logging in. Only specify if you aren't using any of the defaults.
27
30
  #
28
31
  # * <tt>login_field_type</tt> - default: options[:login_field] == :email ? :email : :login,
29
32
  # Tells authlogic how to validation the field, what regex to use, etc. If the field name is email it will automatically use :email,
30
33
  # otherwise it uses :login.
34
+ #
35
+ # * <tt>validate_login_field</tt> - default: true,
36
+ # Tells authlogic if it should validate the :login_field. If set to false, no validations will be set for this field at all.
31
37
  #
32
38
  # * <tt>login_field_regex</tt> - default: if :login_field_type is :email then typical email regex, otherwise typical login regex.
33
39
  # This is used in validates_format_of for the :login_field.
@@ -38,6 +44,9 @@ module Authlogic
38
44
  # * <tt>email_field</tt> - default: :email, depending on if it is present, if :email is not present defaults to nil
39
45
  # The name of the field used to store the email address. Only specify this if you arent using this as your :login_field.
40
46
  #
47
+ # * <tt>validate_email_field</tt> - default: true,
48
+ # Tells Authlogic if it should validate the email field. If set to false, no validations will be set for this field at all.
49
+ #
41
50
  # * <tt>email_field_regex</tt> - default: type email regex
42
51
  # This is used in validates_format_of for the :email_field.
43
52
  #
@@ -52,30 +61,34 @@ module Authlogic
52
61
  #
53
62
  # * <tt>password_field</tt> - default: :password,
54
63
  # This is the name of the field to set the password, *NOT* the field the encrypted password is stored. Defaults the what the configuration
55
- #
56
- # * <tt>crypted_password_field</tt> - default: :crypted_password, :encrypted_password, :password_hash, :pw_hash, depends on which columns are present, if none are present defaults to nil
57
- # The name of the database field where your encrypted password is stored.
64
+ #
65
+ # * <tt>validate_password_field</tt> - default: :password,
66
+ # Tells authlogic if it should validate the :password_field. If set to false, no validations will be set for this field at all.
58
67
  #
59
68
  # * <tt>password_blank_message</tt> - default: "can not be blank",
60
69
  # The error message used when the password is left blank.
61
70
  #
62
71
  # * <tt>confirm_password_did_not_match_message</tt> - default: "did not match",
63
72
  # The error message used when the confirm password does not match the password
64
- #
73
+ #
74
+ # * <tt>crypted_password_field</tt> - default: :crypted_password, :encrypted_password, :password_hash, :pw_hash, depends on which columns are present, if none are present defaults to nil
75
+ # The name of the database field where your encrypted password is stored.
76
+ #
65
77
  # * <tt>password_salt_field</tt> - default: :password_salt, :pw_salt, or :salt, depending on which column is present, defaults to :password_salt if none are present,
66
78
  # This is the name of the field in your database that stores your password salt.
67
79
  #
68
- # * <tt>password_reset_token_field</tt> - default: :password_reset_token, :pw_reset_token, :reset_password_token, or :reset_pw_token, depending on which column is present, if none are present defaults to nil
69
- # This is the name of the field in your database that stores your password reset token. The token you should use to verify your users before you allow a password reset. Authlogic takes care
70
- # of maintaining this for you and making sure it changes when needed.
80
+ # * <tt>perishable_token_field</tt> - default: :perishable_token, :password_reset_token, :pw_reset_token, :reset_password_token, or :reset_pw_token, depending on which column is present, if none are present defaults to nil
81
+ # This is the name of the field in your database that stores your perishable token. The token you should use to confirm your users or allow a password reset. Authlogic takes care
82
+ # of maintaining this for you and making sure it changes when needed. Use this token for whatever you want, but keep in mind it is temporary, hence the term "perishable".
71
83
  #
72
- # * <tt>password_reset_token_valid_for</tt> - default: 10.minutes,
73
- # Authlogic gives you a sepcial method for finding records by the password reset token (see Authlogic::ORMAdapters::ActiveRecordAdapter::ActcsAsAuthentic::PasswordReset). In this method
74
- # it checks for the age of the token. If the token is old than whatever you specify here, a user will NOT be returned. This way the tokens are perishable, thus making this system much
84
+ # * <tt>perishable_token_valid_for</tt> - default: 10.minutes,
85
+ # Authlogic gives you a sepcial method for finding records by the perishable token (see Authlogic::ORMAdapters::ActiveRecordAdapter::ActcsAsAuthentic::Perishability). In this method
86
+ # it checks for the age of the token. If the token is older than whatever you specify here, a record will NOT be returned. This way the tokens are perishable, thus making this system much
75
87
  # more secure.
76
88
  #
77
- # * <tt>remember_token_field</tt> - default: :remember_token, :remember_key, :cookie_tokien, or :cookie_key, depending on which column is present, defaults to :remember_token if none are present,
78
- # This is the name of the field your remember_token is stored. The remember token is a unique token that is stored in the users cookie and
89
+ # * <tt>persistence_field</tt> - default: :persistence_token, :remember_token, or :cookie_tokien, depending on which column is present,
90
+ # defaults to :persistence_token if none are present,
91
+ # This is the name of the field your persistence token is stored. The persistence token is a unique token that is stored in the users cookie and
79
92
  # session. This way you have complete control of when sessions expire and you don't have to change passwords to expire sessions. This also
80
93
  # ensures that stale sessions can not be persisted. By stale, I mean sessions that are logged in using an outdated password.
81
94
  #
@@ -107,10 +120,13 @@ module Authlogic
107
120
 
108
121
  options[:session_class] ||= "#{name}Session"
109
122
  options[:crypto_provider] ||= CryptoProviders::Sha512
123
+ options[:validate_fields] = true unless options.key?(:validate_fields)
110
124
  options[:login_field] ||= first_column_to_exist(:login, :username, :email)
111
125
  options[:login_field_type] ||= options[:login_field] == :email ? :email : :login
126
+ options[:validate_login_field] = true unless options.key?(:validate_login_field)
112
127
  options[:email_field] = first_column_to_exist(nil, :email) unless options.key?(:email_field)
113
128
  options[:email_field] = nil if options[:email_field] == options[:login_field]
129
+ options[:validate_email_field] = true unless options.key?(:validate_email_field)
114
130
 
115
131
  email_name_regex = '[\w\.%\+\-]+'
116
132
  domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
@@ -128,15 +144,17 @@ module Authlogic
128
144
  end
129
145
 
130
146
  options[:password_field] ||= :password
147
+ options[:validate_password_field] = true unless options.key?(:validate_password_field)
148
+
131
149
  options[:password_blank_message] ||= "can not be blank"
132
150
  options[:confirm_password_did_not_match_message] ||= "did not match"
133
151
  options[:crypted_password_field] ||= first_column_to_exist(:crypted_password, :encrypted_password, :password_hash, :pw_hash)
134
152
  options[:password_salt_field] ||= first_column_to_exist(:password_salt, :pw_salt, :salt)
135
- options[:remember_token_field] ||= first_column_to_exist(:remember_token, :remember_key, :cookie_token, :cookiey_key)
153
+ options[:persistence_token_field] ||= options[:remember_token_field] || first_column_to_exist(:persistence_token, :remember_token, :cookie_token)
136
154
  options[:single_access_token_field] ||= first_column_to_exist(nil, :single_access_token, :feed_token, :feeds_token)
137
- options[:password_reset_token_field] ||= first_column_to_exist(nil, :password_reset_token, :pw_reset_token, :reset_password_token, :reset_pw_token)
138
- options[:password_reset_token_valid_for] ||= 10.minutes
139
- options[:password_reset_token_valid_for] = options[:password_reset_token_valid_for].to_i
155
+ options[:perishable_token_field] ||= options[:password_reset_token_field] || first_column_to_exist(nil, :perishable_token, :password_reset_token, :pw_reset_token, :reset_password_token, :reset_pw_token, :activation_token)
156
+ options[:perishable_token_valid_for] ||= 10.minutes
157
+ options[:perishable_token_valid_for] = options[:perishable_token_valid_for].to_i
140
158
  options[:logged_in_timeout] ||= 10.minutes
141
159
  options[:logged_in_timeout] = options[:logged_in_timeout].to_i
142
160
  options[:session_ids] ||= [nil]
@@ -19,25 +19,29 @@ module Authlogic
19
19
  module Credentials
20
20
  def acts_as_authentic_with_credentials(options = {})
21
21
  acts_as_authentic_without_credentials(options)
22
-
23
- # Validations
24
- case options[:login_field_type]
25
- when :email
26
- validates_length_of options[:login_field], :within => 6..100
27
- validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
28
- else
29
- validates_length_of options[:login_field], :within => 2..100, :allow_blank => true
30
- validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
31
- end
32
22
 
33
- if options[:email_field]
34
- validates_length_of options[:email_field], :within => 6..100
35
- validates_format_of options[:email_field], :with => options[:email_field_regex], :message => options[:email_field_regex_failed_message]
36
- validates_uniqueness_of options[:email_field], :scope => options[:scope]
37
- end
23
+ if options[:validate_fields]
24
+ if options[:validate_login_field]
25
+ case options[:login_field_type]
26
+ when :email
27
+ validates_length_of options[:login_field], :within => 6..100
28
+ validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
29
+ else
30
+ validates_length_of options[:login_field], :within => 2..100, :allow_blank => true
31
+ validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
32
+ end
33
+
34
+ validates_uniqueness_of options[:login_field], :scope => options[:scope]
35
+ end
36
+
37
+ if options[:validate_email_field] && options[:email_field]
38
+ validates_length_of options[:email_field], :within => 6..100
39
+ validates_format_of options[:email_field], :with => options[:email_field_regex], :message => options[:email_field_regex_failed_message]
40
+ validates_uniqueness_of options[:email_field], :scope => options[:scope]
41
+ end
38
42
 
39
- validates_uniqueness_of options[:login_field], :scope => options[:scope]
40
- validate :validate_password
43
+ validate :validate_password if options[:validate_password_field]
44
+ end
41
45
 
42
46
  attr_writer "confirm_#{options[:password_field]}"
43
47
  attr_accessor "tried_to_set_#{options[:password_field]}"
@@ -0,0 +1,75 @@
1
+ module Authlogic
2
+ module ORMAdapters
3
+ module ActiveRecordAdapter
4
+ module ActsAsAuthentic
5
+ # = Perishable
6
+ #
7
+ # Handles all logic the deals with maintaining the perishable token. This token should be used to authenticate a user that is not logged in so that they
8
+ # can change their password, confirm their account, etc. Use it for whatever you want, but keep in mind this token is only temporary. Which
9
+ # is perfect for emailing, etc.
10
+ #
11
+ # === Class Methods
12
+ #
13
+ # * <tt>find_using_{options[:perishable_token_field]}(token, age = {options[:perishable_token_valid_for]})</tt> - returns the record that matches the pased token. The record's updated at column must not be older than
14
+ # {age} ago. Lastly, if a blank token is passed no record will be returned.
15
+ #
16
+ # === Instance Methods
17
+ #
18
+ # * <tt>reset_#{options[:perishable_token_field]}</tt> - resets the perishable token field to a friendly unique token.
19
+ # * <tt>reset_#{options[:perishable_token_field]}!</tt> - same as above but saves the record afterwards.
20
+ module Perishability
21
+ def acts_as_authentic_with_perishability(options = {})
22
+ acts_as_authentic_without_perishability(options)
23
+
24
+ return if options[:perishable_token_field].blank?
25
+
26
+ class_eval <<-"end_eval", __FILE__, __LINE__
27
+ validates_uniqueness_of :#{options[:perishable_token_field]}
28
+
29
+ before_validation :reset_#{options[:perishable_token_field]}, :unless => :resetting_#{options[:perishable_token_field]}?
30
+
31
+ def self.find_using_#{options[:perishable_token_field]}(token, age = #{options[:perishable_token_valid_for]})
32
+ return if token.blank?
33
+ age = age.to_i
34
+
35
+ conditions_sql = "#{options[:perishable_token_field]} = ?"
36
+ conditions_subs = [token]
37
+
38
+ if column_names.include?("updated_at") && age > 0
39
+ conditions_sql += " and updated_at > ?"
40
+ conditions_subs << age.seconds.ago
41
+ end
42
+
43
+ find(:first, :conditions => [conditions_sql, *conditions_subs])
44
+ end
45
+
46
+ def reset_#{options[:perishable_token_field]}
47
+ self.#{options[:perishable_token_field]} = self.class.friendly_unique_token
48
+ end
49
+
50
+ def reset_#{options[:perishable_token_field]}!
51
+ reset_#{options[:perishable_token_field]}
52
+ @resetting_#{options[:perishable_token_field]} = true
53
+ result = save_without_session_maintenance
54
+ @resetting_#{options[:perishable_token_field]} = false
55
+ result
56
+ end
57
+
58
+ private
59
+ def resetting_#{options[:perishable_token_field]}?
60
+ @resetting_#{options[:perishable_token_field]} == true
61
+ end
62
+ end_eval
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ ActiveRecord::Base.class_eval do
71
+ class << self
72
+ include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Perishability
73
+ alias_method_chain :acts_as_authentic, :perishability
74
+ end
75
+ end