authlogic 1.3.4 → 1.3.5

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.

@@ -1,3 +1,12 @@
1
+ == 1.3.5 released 2008-11-30
2
+
3
+ * :transition_from_crypto_provider for acts_as_authentic now accepts an array to transition from multiple providers. Which solves the problem of a double transition.
4
+ * Added AES256 as a crypto_provider option, for those that want to use a reversible encryption method by supplying a key.
5
+ * Fixed typo for using validates_format_of_options instead of validates_length_of_options
6
+ * Fixed bug when accessing the dynamic method for accessing the session record in a namespace, since it uses class_name.underscore which replaces :: with a /
7
+ * Added minimum length requirement of 4 for the password, and removed validates_presence_of for password since validates_length_of enforces this
8
+ * Set before_validation to reset the persistence token if it is blank, since a password is not required for open id authentication
9
+
1
10
  == 1.3.4 released 2008-11-24
2
11
 
3
12
  * Delegate human_attribute_name to the ActiveRecord class to take advantage of the I18n feature.
data/Manifest CHANGED
@@ -3,6 +3,7 @@ init.rb
3
3
  lib/authlogic/controller_adapters/abstract_adapter.rb
4
4
  lib/authlogic/controller_adapters/merb_adapter.rb
5
5
  lib/authlogic/controller_adapters/rails_adapter.rb
6
+ lib/authlogic/crypto_providers/aes256.rb
6
7
  lib/authlogic/crypto_providers/bcrypt.rb
7
8
  lib/authlogic/crypto_providers/sha1.rb
8
9
  lib/authlogic/crypto_providers/sha512.rb
@@ -33,11 +34,14 @@ MIT-LICENSE
33
34
  Rakefile
34
35
  README.rdoc
35
36
  shoulda_macros/authlogic.rb
37
+ test/crypto_provider_tests/aes256_test.rb
38
+ test/crypto_provider_tests/bcrypt_test.rb
39
+ test/crypto_provider_tests/sha1_test.rb
40
+ test/crypto_provider_tests/sha512_test.rb
36
41
  test/fixtures/companies.yml
37
42
  test/fixtures/employees.yml
38
43
  test/fixtures/projects.yml
39
44
  test/fixtures/users.yml
40
- test/libs/aes128_crypto_provider.rb
41
45
  test/libs/mock_controller.rb
42
46
  test/libs/mock_cookie_jar.rb
43
47
  test/libs/mock_request.rb
@@ -2,7 +2,7 @@
2
2
 
3
3
  Authlogic is a clean, simple, and unobtrusive ruby authentication solution. Put simply, its the Chuck Norris of authentication solutions for your framework of choice.
4
4
 
5
- The last thing we need is another authentication solution, right? That's what I thought until I tried out some of the current solutions in both rails and merb. None of them felt right. They were either too complicated, bloated, littered my application with tons of code, or were just confusing. This is not the simple / elegant ruby we all fell in love with. We need a "ruby like" authentication solution. Authlogic is my attempt to satisfy that need...
5
+ So what is Authlogic, and why would I create a solution to a problem that already has plenty of solutions? Because none of the solutions felt right to me, RESTful development and authentication just didn't seem to go well together. It was like trying to fit a square peg in a round hole. All of the current solutions, for both rails and merb, just seemed to force that square peg in the round hole for me. Just because they did it for me doesn't make it right. They were either too complicated, bloated, littered my application with tons of code, had no platform for reasonable updating, used an inferior encryption algorithm, or were just confusing. This is not the simple / elegant ruby we all fell in love with. We need a "ruby like" authentication solution. Authlogic is my attempt to satisfy that need...
6
6
 
7
7
  Let's take a rails application...
8
8
 
@@ -66,7 +66,7 @@ Or how about persisting the session...
66
66
  end
67
67
  end
68
68
 
69
- Authlogic makes this a reality. This is just the tip of the ice berg. Keep reading to find out everything Authlogic can do.
69
+ Authlogic and REST are like peas and carrots, as Forrest Gump would say. But This is just the tip of the ice berg. Keep reading to find out everything Authlogic can do.
70
70
 
71
71
  == Helpful links
72
72
 
@@ -116,7 +116,7 @@ The user model needs to have the following columns. The names of these columns c
116
116
  t.string :persistence_token, :null => false
117
117
  t.string :single_access_token, :null => false # optional, see the tokens section below.
118
118
  t.string :perishable_token, :null => false # optional, see the tokens section below.
119
- t.integer :login_count # optional, this is a "magic" column, see the magic columns section below
119
+ t.integer :login_count, :null => false, :default => 0 # optional, this is a "magic" column, see the magic columns section below
120
120
 
121
121
  === Set up your model
122
122
 
@@ -130,6 +130,36 @@ One thing to keep in mind here is that the default :crypto_provider for Authlogi
130
130
 
131
131
  You are all set, now go use it just like you would with any other ActiveRecord model. Either glance at the code at the beginning of this README or check out the tutorials (see above in "helpful links") for a more detailed walk through.
132
132
 
133
+ == Migrating an existing app from restful_authentication and upgrading your encryption
134
+
135
+ For those that are switching existing apps over, I made an option especially for you. Just do the following and everything will be taken care of, your users won't even know anything changed:
136
+
137
+ # app/models/user.rb
138
+ class User < ActiveRecord::Base
139
+ acts_as_authentic :act_like_restful_authentication => true
140
+ end
141
+
142
+ The above will not change a thing, from your database's perspective it will be as if you are still using restful_authentication.
143
+
144
+ Or you can upgrade from Sha1 and transition your users to a much more secure encryption algorithm:
145
+
146
+ # app/models/user.rb
147
+ class User < ActiveRecord::Base
148
+ acts_as_authentic :transition_from_restful_authentication => true
149
+ end
150
+
151
+ By default this will switch your users to Authlogic's Sha512 implementation. You do *NOT* have to use this. Check out the encryption methods section below for a list of encryption methods Authlogic provides you. If you want to use something besides Sha512 just specify it by doing:
152
+
153
+ # app/models/user.rb
154
+ class User < ActiveRecord::Base
155
+ acts_as_authentic :transition_from_restful_authentication => true,
156
+ :crypto_provider => Authlogic::CryptoProviders::BCrypt
157
+ end
158
+
159
+ Every time a user logs in their password will be upgraded and every time a new account is created it will use the new algorithm all while allowing users to login with the old algorithm.
160
+
161
+ For more information checkout my blog post on this: http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic
162
+
133
163
  == Magic Columns
134
164
 
135
165
  Just like ActiveRecord has "magic" columns, such as: created_at and updated_at. Authlogic has its own "magic" columns too:
@@ -150,6 +180,8 @@ Authlogic tries to check the state of the record before creating the session. If
150
180
  active? Is the record marked as active?
151
181
  approved? Has the record been approved?
152
182
  confirmed? Has the record been conirmed?
183
+
184
+ Authlogic does nothing to define these methods for you, its up to you to define what they mean. If your object responds to these methods Authlogic will use them, otherwise they are ignored.
153
185
 
154
186
  What's neat about this is that these are checked upon any type of login. When logging in explicitly, by cookie, session, or basic http auth. So if you mark a user inactive in the middle of their session they wont be logged back in next time they refresh the page. Giving you complete control.
155
187
 
@@ -161,14 +193,19 @@ Just like ActiveRecord you can create your own hooks / callbacks so that you can
161
193
 
162
194
  before_create
163
195
  after_create
196
+
164
197
  before_destroy
165
198
  after_destroy
199
+
166
200
  before_find
167
201
  after_find
202
+
168
203
  before_save
169
204
  after_save
205
+
170
206
  before_update
171
207
  after_update
208
+
172
209
  before_validation
173
210
  after_validation
174
211
 
@@ -199,11 +236,12 @@ For more information on ids checkout Authlogic::Session::Base#id
199
236
 
200
237
  == Encryption methods
201
238
 
202
- Authlogic is designed so you can use *any* encryption method you want. It delegates this task to a class of your choice. Here are you choices:
239
+ Authlogic is designed so you can use *any* encryption method you want. It delegates this task to a class of your choice. Authlogic comes preloaded with some common algorithms:
203
240
 
204
241
  1. Authlogic::CryptoProviders::Sha1 (used mainly for migrating from restful_authentication)
205
- 2. Authlogic::CryptoProviders::Sha512
206
- 3. Authlogic::CryptoProviders::BCrypt
242
+ 2. Authlogic::CryptoProviders::Sha512 (default)
243
+ 3. Authlogic::CryptoProviders::BCrypt (requires bcrypt-ruby gem)
244
+ 4. Authlogic::CryptoProviders::AES256 (requires you to supply a key, see the AES256 class in the docs for more info)
207
245
 
208
246
  By default Authlogic uses salted Sha512 with 20 stretches, but you can easily change this. For example, if you wanted to use the BCrypt algorithm just do the following:
209
247
 
@@ -211,7 +249,7 @@ By default Authlogic uses salted Sha512 with 20 stretches, but you can easily ch
211
249
 
212
250
  For more information on BCrypt checkout my blog post on it: http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic
213
251
 
214
- Also, check out the Authlogic::CryptoProviders module and subclasses to get an idea of how to write your own crypto provider. You don't have to use the provided classes, you can easily write your own. All that you have to do is make a class with a class level encrypt and matches? method. That's it, the sky is the limit.
252
+ Also, check out the Authlogic::CryptoProviders module and subclasses to get an idea of how to write your own crypto provider. You don't have to use the provided classes, you can easily write your own. All that you have to do is make a class with a class level encrypt and matches? method. That's it, all of the encryption and decryption logic is left to you.
215
253
 
216
254
  == Switching to a new encryption method
217
255
 
@@ -222,6 +260,15 @@ Switching to a new encryption method used to be a pain in the ass. Authlogic has
222
260
 
223
261
  That's it. When a user successfully logs in and is using the old method their password will be updated with the new method and all new registrations will use the new method as well. Your users won't know anything changed.
224
262
 
263
+ But wait, what if a couple of years later CCrypt comes out and its better than BCrypt and you're still in the middle of transitioning all of your users to BCrypt. Oh no!
264
+
265
+ Not to worry, because Authlogic can transition your users from more than one algorithm. Just pass an array to :transition_from_crypto_provider
266
+
267
+ acts_as_authentic :crypto_provider => CCrypt,
268
+ :transition_from_crypto_provider => [Authlogic::CryptoProviders::Sha512, Authlogic::CryptoProviders::BCrypt]
269
+
270
+ That's it, specify as many as you want. One thing to keep in mind here is that if you are using BCrypt you should never have to do this. All that you need to do is increase the cost to make the algorithm stronger, no need to jump to entirely new algorithm. I did this for example purposes only.
271
+
225
272
  == Tokens (persistence, resetting passwords, private feed access, etc.)
226
273
 
227
274
  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:
@@ -235,11 +282,11 @@ There could be many more depending on your application. What's great about Authl
235
282
 
236
283
  Here are the 3 tokens in more detail:
237
284
 
238
- === Persistence token
285
+ === 1. Persistence token (stored in cookie / session)
239
286
 
240
287
  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.
241
288
 
242
- === Single access token
289
+ === 2. Single access token (private feed access, etc.)
243
290
 
244
291
  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. For added security, by default this token is *ONLY* allowed for RSS and ATOM requests. Also, this token does *NOT* change with the password. Meaning if the user changes their password, this token will remain the same. Lastly, this token uses a "friendly" toke (see the URL example below) so that it is easier to email / copy and paste. 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.
245
292
 
@@ -256,7 +303,7 @@ The single_access_token parameter name is configurable (see Authlogic::Session::
256
303
 
257
304
  For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::SingleAccess
258
305
 
259
- === Perishable token
306
+ === 3. Perishable token (resetting passwords, confirming accounts, etc)
260
307
 
261
308
  This token is used for temporary account access, hence the term "perishable". This token is constantly changing, it changes...
262
309
 
@@ -367,7 +414,7 @@ The errors in Authlogic work JUST LIKE ActiveRecord. In fact, it uses the exact
367
414
 
368
415
  This is one of my favorite features that I think is pretty cool. It's things like this that make a library great and let you know you are on the right track.
369
416
 
370
- Just to clear up any confusion, Authlogic does not store the plain id in the session. It stores a token. This token changes with the password, this way stale sessions can not be persisted.
417
+ Just to clear up any confusion, Authlogic stores both the record id and the persistence token in the session. Why? So stale sessions can not be persisted. It stores the id so it can quickly find the record, and the persistence token to ensure no sessions are stale. The persistence token changes with the password, if someone is logged in and their password is changed, they should be logged out, unless they made the change. That being said, the person making the change needs their session to be updated with the new persistence token, so they stay logged in, which is what this section is all about.
371
418
 
372
419
  That being said...What if a user changes their password? You have to re-log them in with the new password, recreate the session, etc, pain in the ass. Or what if a user creates a new user account? You have to do the same thing. Here's an even better one: what if a user is in the admin area and changes his own password? There might even be another place passwords can change. It shouldn't matter, your code should be written in a way where you don't have to remember to do this.
373
420
 
@@ -382,51 +429,33 @@ Here is basically how this is done....
382
429
 
383
430
  private
384
431
  def maintain_sessions!
385
- # If we aren't logged in and a user is create log them in as that user
432
+ # If we aren't logged in and a user is created, log them in as that user
386
433
  # If we aren't logged in and a user's password changes, log them in as that user
387
434
  # If we are logged in and they change their password, update the session so they remain logged in
388
435
  end
389
436
  end
390
437
 
391
- Obviously there is a little more to it than this, but hopefully this clarifies any confusion. Lastly, this can be altered / disabled via a configuration option. Just set :session_ids => nil when calling acts_as_authentic.
438
+ Obviously there is a little more to it than this, but hopefully this clarifies any confusion. Basically if you are *logged out* and you are changing passwords, Authlogic will log you in, since you already know the password for that account. Lastly, this can be altered / disabled via a configuration option. Just set :session_ids => nil when calling acts_as_authentic.
392
439
 
393
440
  When things come together like this I think its a sign that you are doing something right. Put that in your pipe and smoke it!
394
441
 
395
- == Migrating from restful_authentication
396
-
397
- Migrating from the restful_authentication plugin? I made an option especially for you. Just do the following and everything will be taken care of, your users won't even know anything changed:
398
-
399
- # app/models/user.rb
400
- class User < ActiveRecord::Base
401
- acts_as_authentic :act_like_restful_authentication => true
402
- end
403
-
404
- Or you can transition your users to the Authlogic password system:
405
-
406
- # app/models/user.rb
407
- class User < ActiveRecord::Base
408
- acts_as_authentic :transition_from_restful_authentication => true
409
- end
410
-
411
- For more information checkout my blog post on this: http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic
412
-
413
442
  == Framework agnostic (Rails, Merb, etc.)
414
443
 
415
444
  I designed Authlogic to be framework agnostic, meaning it doesn't care what framework you use it in. Right out of the box it supports rails and merb. I have not had the opportunity to use other frameworks, but the only thing stopping Authlogic from being used in other frameworks is a simple adapter. Check out controller_adapters/rails_adapter, or controller_adapters/merb_adapter.
416
445
 
417
- Since pretty much all of the frameworks in ruby follow the Rack conventions, the code should be very similar across adapters. In fact that abstract adapter assumes you are using Rack. If you are using it properly there really isn't any code you should have to write. Check out the merb_adapter to see for yourself. You're saying "but Ben, why not just hook into Rack and avoid the need for controller adapters all together?". It's not that simple, because rails doesn't inherit from the Rack::Request class, plus there are small differences between how rack is implemented in each framework. Authlogic has to hook into your controller with a before_filter anyways, so it can "activate" itself. Why not just use the controller object?
446
+ Since pretty much all of the frameworks in ruby follow the Rack standards, the code should be very similar across adapters. In fact that abstract adapter assumes you are following the Rack standards. If your framework is following the rack standards, there really isn't any code you should have to write. Check out the merb_adapter to see for yourself, the merb adapter is basically blank. You're saying "but Ben, why not just hook into Rack and avoid the need for controller adapters all together?". It's not that simple, because rails doesn't inherit from the Rack::Request class, plus there are small differences between how rack is implemented in each framework. Authlogic has to hook into your controller with a before_filter anyways, so it can "activate" itself. Why not just use the controller object? Also when we have access to the controller object we can do other nifty things. Checkout the OpenID tutorial in the helpful links section above to see what I mean.
418
447
 
419
448
  The point in all of this rambling is that implementing Authlogic is as simple as creating an adapter. I created both the rails and merb adapters in under 10 minutes. If you have an adapter you created and would like to add please let me know and I will add it into the source.
420
449
 
421
450
  == How it works
422
451
 
423
- Interested in how all of this all works? Basically a before_filter is automatically set in your controller which lets Authlogic know about the current controller object. This "activates" Authlogic and allows Authlogic to set sessions, cookies, login via basic http auth, etc. If you are using your framework in a multiple thread environment, don't worry. I kept that in mind and made this thread safe.
452
+ Interested in how all of this all works? Basically a before filter is automatically set in your controller which lets Authlogic know about the current controller object. This "activates" Authlogic and allows Authlogic to set sessions, cookies, login via basic http auth, etc. If you are using your framework in a multiple thread environment, don't worry. I kept that in mind and made this thread safe.
424
453
 
425
454
  From there it is pretty simple. When you try to create a new session the record is authenticated and then all of the session / cookie magic is done for you. The sky is the limit.
426
455
 
427
456
  == What's wrong with the current solutions?
428
457
 
429
- You probably don't care, but I think releasing the millionth authentication solution for a framework that has been around for over 4 years requires a little explanation.
458
+ You probably don't care, but I think releasing the millionth ruby authentication solution requires a little explanation.
430
459
 
431
460
  I don't necessarily think the current solutions are "wrong", nor am I saying Authlogic is the answer to your prayers. But, to me, the current solutions were lacking something. Here's what I came up with...
432
461
 
@@ -440,6 +469,10 @@ Using a library that hundreds of other people use has it advantages. Probably on
440
469
 
441
470
  Lastly, there is a pattern here, why clutter up all of your applications with the same code over and over?
442
471
 
472
+ === Security gets outdated
473
+
474
+ Just as I stated in the above section, you can't stay up to date with your security since the code is generated and updating the plugin does nothing. If there is one thing you should stay up to date with, it's security. But it's not just the fact that there is no reasonable method for receiving updates. It's the fact that they tie you down to an encryption algorithm *AND* they use a bad one at that. Every single solution I've seen uses Sha1, which is joining the party with MD5. Sha1 is not as secure as it used to be. But that's the nature of algorithms, they eventually get phased out, which is fine. Everyone knows this, why not accommodate for this? Authlogic does this with the :transition_from_crypto_provider option. It takes care of transitioning all of your users to a new algorithm. Even better, it provides BCrypt as an option which should, in theory, never require you to switch since you can adjust the cost and make the encryption stronger. At the same time, still compatible with older passwords using the lower cost.
475
+
443
476
  === Why test the same code over and over?
444
477
 
445
478
  I've noticed my apps get cluttered with authentication tests, and they are the same exact tests! This irritates me. When you have identical tests across your apps thats a red flag that code can be extracted into a library. What's great about Authlogic is that I tested it for you. You don't write tests that test the internals of ActiveRecord do you? The same applies for Authlogic. Only test code that you've written. Essentially testing authentication is similar to testing any another RESTful controller. This makes your tests focused and easier to understand.
@@ -454,7 +487,7 @@ A lot of them forced me to name my password column as "this", or the key of my c
454
487
 
455
488
  === Disclaimer
456
489
 
457
- I am not trying to "bash" any other authentication solutions. These are just my opinions, formulate your own opinion. I released Authlogic because it has made my life easier and I enjoy using it, hopefully it does the same for you.
490
+ I am not trying to "bash" any other authentication solutions. These are just my opinions, formulate your own opinion. I released Authlogic because I was "scratching my own itch". It has made my life easier and I enjoy using it, hopefully it does the same for you.
458
491
 
459
492
 
460
493
  Copyright (c) 2008 Ben Johnson of [Binary Logic](http://www.binarylogic.com), released under the MIT license
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{authlogic}
5
- s.version = "1.3.4"
5
+ s.version = "1.3.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ben Johnson of Binary Logic"]
9
- s.date = %q{2008-11-24}
9
+ s.date = %q{2008-11-30}
10
10
  s.description = %q{A clean, simple, and unobtrusive ruby authentication solution.}
11
11
  s.email = %q{bjohnson@binarylogic.com}
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/bcrypt.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/bcrypt.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", "test/crypto_provider_tests/bcrypt_test.rb", "test/crypto_provider_tests/sha1_test.rb", "test/crypto_provider_tests/sha512_test.rb"]
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/aes256.rb", "lib/authlogic/crypto_providers/bcrypt.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/aes256.rb", "lib/authlogic/crypto_providers/bcrypt.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/crypto_provider_tests/aes256_test.rb", "test/crypto_provider_tests/bcrypt_test.rb", "test/crypto_provider_tests/sha1_test.rb", "test/crypto_provider_tests/sha512_test.rb", "test/fixtures/companies.yml", "test/fixtures/employees.yml", "test/fixtures/projects.yml", "test/fixtures/users.yml", "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"]
14
14
  s.has_rdoc = true
15
15
  s.homepage = %q{http://github.com/binarylogic/authlogic}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Authlogic", "--main", "README.rdoc"]
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.rubyforge_project = %q{authlogic}
19
19
  s.rubygems_version = %q{1.3.1}
20
20
  s.summary = %q{A clean, simple, and unobtrusive ruby authentication solution.}
21
- s.test_files = ["test/crypto_provider_tests/bcrypt_test.rb", "test/crypto_provider_tests/sha1_test.rb", "test/crypto_provider_tests/sha512_test.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"]
21
+ s.test_files = ["test/crypto_provider_tests/aes256_test.rb", "test/crypto_provider_tests/bcrypt_test.rb", "test/crypto_provider_tests/sha1_test.rb", "test/crypto_provider_tests/sha512_test.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"]
22
22
 
23
23
  if s.respond_to? :specification_version then
24
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -9,6 +9,7 @@ require File.dirname(__FILE__) + "/authlogic/controller_adapters/merb_adapter" i
9
9
  require File.dirname(__FILE__) + "/authlogic/crypto_providers/sha1"
10
10
  require File.dirname(__FILE__) + "/authlogic/crypto_providers/sha512"
11
11
  require File.dirname(__FILE__) + "/authlogic/crypto_providers/bcrypt"
12
+ require File.dirname(__FILE__) + "/authlogic/crypto_providers/aes256"
12
13
 
13
14
  if defined?(ActiveRecord)
14
15
  require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic"
@@ -1,10 +1,12 @@
1
1
  module Authlogic
2
2
  module ControllerAdapters
3
3
  # = Merb Adapter
4
+ #
4
5
  # Adapts authlogic to work with merb. The point is to close the gap between what authlogic expects and what the merb controller object
5
6
  # provides. Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite, etc.
6
7
  class MerbAdapter < AbstractAdapter
7
8
  # = Merb Implementation
9
+ #
8
10
  # Lets Authlogic know about the controller object, AKA "activates" authlogic.
9
11
  module MerbImplementation
10
12
  def self.included(klass) # :nodoc:
@@ -1,6 +1,7 @@
1
1
  module Authlogic
2
2
  module ControllerAdapters
3
3
  # = Rails Adapter
4
+ #
4
5
  # Adapts authlogic to work with rails. The point is to close the gap between what authlogic expects and what the rails controller object
5
6
  # provides. Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite, etc.
6
7
  class RailsAdapter < AbstractAdapter
@@ -17,6 +18,7 @@ module Authlogic
17
18
  end
18
19
 
19
20
  # = Rails Implementation
21
+ #
20
22
  # Lets Authlogic know about the controller object, AKA "activates" authlogic.
21
23
  module RailsImplementation
22
24
  def self.included(klass) # :nodoc:
@@ -0,0 +1,45 @@
1
+ require "openssl"
2
+
3
+ module Authlogic
4
+ module CryptoProviders
5
+ # = AES256
6
+ #
7
+ # This encryption method is reversible if you have the supplied key. So in order to use this encryption method you must supply it with a key first.
8
+ # In an initializer, or before your application initializes, you should do the following:
9
+ #
10
+ # Authlogic::CryptoProviders::AES256.key = "my really long and unique key, preferrable a bunch of random characters"
11
+ #
12
+ # My final comment is that this is a strong encryption method, but its main weakness is that its reversible. If you do not need to reverse the hash
13
+ # then you should consider Sha512 or BCrypt instead.
14
+ #
15
+ # Keep your key in a safe place, some even say the key should be stored on a separate server.
16
+ # This won't hurt performance because the only time it will try and access the key on the separate server is during initialization, which only
17
+ # happens once. The reasoning behind this is if someone does compromise your server they won't have the key also. Basically, you don't want to
18
+ # store the key with the lock.
19
+ class AES256
20
+ class << self
21
+ attr_writer :key
22
+
23
+ def encrypt(*tokens)
24
+ aes.encrypt
25
+ aes.key = @key
26
+ [aes.update(tokens.join) + aes.final].pack("m").chomp
27
+ end
28
+
29
+ def matches?(crypted, *tokens)
30
+ aes.decrypt
31
+ aes.key = @key
32
+ (aes.update(crypted.unpack("m").first) + aes.final) == tokens.join
33
+ rescue OpenSSL::CipherError
34
+ false
35
+ end
36
+
37
+ private
38
+ def aes
39
+ raise ArgumentError.new("You provide a key like #{name}.key = my_key before using the #{name}") if @key.blank?
40
+ @aes ||= OpenSSL::Cipher::Cipher.new("AES-256-ECB")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -124,8 +124,8 @@ module Authlogic
124
124
  # * <tt>password_field_validation_options</tt> - default: {},
125
125
  # The same as :validation_options but these are only applied to validations that pertain to the :password_field
126
126
  #
127
- # * <tt>password_field_validates_presence_of_options</tt> - default: {:on => :create},
128
- # These options are applied to the validates_presence_of call for the :password_field
127
+ # * <tt>password_field_validates_length_of_options</tt> - default: {:minimum => 4},
128
+ # These options are applied to the validates_length_of call for the :password_field
129
129
  #
130
130
  # * <tt>login_field_validates_confirmation_of_options</tt> - default: {},
131
131
  # These options are applied to the validates_confirmation_of call for the :password_field
@@ -187,7 +187,7 @@ module Authlogic
187
187
  field_key = "#{field_name}_field_validation_options".to_sym
188
188
  options[field_key] = options[:validation_options].merge(options[field_key] || {})
189
189
 
190
- validation_types = field_name == :password ? [:presence, :confirmation] : [:length, :format, :uniqueness]
190
+ validation_types = field_name == :password ? [:length, :confirmation] : [:length, :format, :uniqueness]
191
191
  validation_types.each do |validation_type|
192
192
  validation_key = "#{field_name}_field_validates_#{validation_type}_of_options".to_sym
193
193
  options[validation_key] = options[field_key].merge(options[validation_key] || {})
@@ -207,6 +207,8 @@ module Authlogic
207
207
  options[crypto_provider_key].stretches = 1
208
208
  end
209
209
  end
210
+
211
+ options[:transition_from_crypto_provider] = [options[:transition_from_crypto_provider]].compact unless options[:transition_from_crypto_provider].is_a?(Array)
210
212
 
211
213
  class_eval <<-"end_eval", __FILE__, __LINE__
212
214
  def self.acts_as_authentic_config
@@ -30,7 +30,7 @@ module Authlogic
30
30
  case options[:login_field_type]
31
31
  when :email
32
32
  validates_length_of options[:login_field], {:within => 6..100}.merge(options[:login_field_validates_length_of_options])
33
- validates_format_of options[:login_field], {:with => email_field_regex, :message => "should look like an email address."}.merge(options[:login_field_validates_length_of_options])
33
+ validates_format_of options[:login_field], {:with => email_field_regex, :message => "should look like an email address."}.merge(options[:login_field_validates_format_of_options])
34
34
  else
35
35
  validates_length_of options[:login_field], {:within => 2..100}.merge(options[:login_field_validates_length_of_options])
36
36
  validates_format_of options[:login_field], {:with => /\A\w[\w\.\-_@ ]+\z/, :message => "should use only letters, numbers, spaces, and .-_@ please."}.merge(options[:login_field_validates_format_of_options])
@@ -40,9 +40,9 @@ module Authlogic
40
40
  end
41
41
 
42
42
  if options[:validate_password_field]
43
- validates_presence_of options[:password_field], {:on => :create}.merge(options[:password_field_validates_presence_of_options])
44
- validates_confirmation_of options[:password_field], options[:password_field_validates_confirmation_of_options].merge(:if => "#{options[:crypted_password_field]}_changed?".to_sym)
45
- validates_presence_of "#{options[:password_field]}_confirmation", :if => "#{options[:crypted_password_field]}_changed?"
43
+ validates_length_of options[:password_field], {:minimum => 4}.merge(options[:password_field_validates_length_of_options].merge(:if => "validate_#{options[:password_field]}?".to_sym))
44
+ validates_confirmation_of options[:password_field], options[:password_field_validates_confirmation_of_options].merge(:if => "validate_#{options[:password_field]}?".to_sym)
45
+ validates_presence_of "#{options[:password_field]}_confirmation", :if => "validate_#{options[:password_field]}?".to_sym
46
46
  end
47
47
 
48
48
  if options[:validate_email_field] && options[:email_field]
@@ -73,22 +73,17 @@ module Authlogic
73
73
  def valid_#{options[:password_field]}?(attempted_password)
74
74
  return false if attempted_password.blank? || #{options[:crypted_password_field]}.blank? || #{options[:password_salt_field]}.blank?
75
75
 
76
- [#{options[:crypto_provider]}, #{options[:transition_from_crypto_provider].inspect}].compact.each do |encryptor|
76
+ ([#{options[:crypto_provider]}] + #{options[:transition_from_crypto_provider].inspect}).each_with_index do |encryptor, index|
77
77
  # The arguments_type of for the transitioning from restful_authentication
78
- arguments_type = nil
79
-
80
- case encryptor.name
81
- when "#{options[:crypto_provider]}"
82
- arguments_type = :restful_authentication if #{options[:act_like_restful_authentication].inspect}
83
- when "#{options[:transition_from_crypto_provider].inspect}"
84
- arguments_type = :restful_authentication if #{options[:transition_from_restful_authentication].inspect}
85
- end
78
+ arguments_type = (#{options[:act_like_restful_authentication].inspect} && index == 0) ||
79
+ (#{options[:transition_from_restful_authentication].inspect} && index > 0 && encryptor == Authlogic::CryptoProviders::Sha1) ?
80
+ :restful_authentication : nil
86
81
 
87
82
  if encryptor.matches?(#{options[:crypted_password_field]}, *encrypt_arguments(attempted_password, arguments_type))
88
83
  # If we are transitioning from an older encryption algorithm and the password is still using the old algorithm
89
84
  # then let's reset the password using the new algorithm. If the algorithm has a cost (BCrypt) and the cost has changed, update the password with
90
85
  # the new cost.
91
- if encryptor == #{options[:transition_from_crypto_provider].inspect} || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(#{options[:crypted_password_field]}))
86
+ if index > 0 || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(#{options[:crypted_password_field]}))
92
87
  update_#{options[:password_field]}(attempted_password)
93
88
  save(false)
94
89
  end
@@ -118,6 +113,10 @@ module Authlogic
118
113
  end
119
114
  alias_method :randomize_password!, :reset_password!
120
115
 
116
+ def validate_#{options[:password_field]}?
117
+ new_record? || #{options[:crypted_password_field]}_changed?
118
+ end
119
+
121
120
  private
122
121
  def encrypt_arguments(raw_password, arguments_type = nil)
123
122
  case arguments_type
@@ -22,7 +22,10 @@ module Authlogic
22
22
  def acts_as_authentic_with_persistence(options = {})
23
23
  acts_as_authentic_without_persistence(options)
24
24
 
25
+ validates_presence_of options[:persistence_token_field]
25
26
  validates_uniqueness_of options[:persistence_token_field], :if => "#{options[:persistence_token_field]}_changed?".to_sym
27
+
28
+ before_validation "reset_#{options[:persistence_token_field]}".to_sym, :if => "reset_#{options[:persistence_token_field]}?".to_sym
26
29
 
27
30
  def forget_all!
28
31
  # Paginate these to save on memory
@@ -46,10 +49,23 @@ module Authlogic
46
49
  end
47
50
 
48
51
  def #{options[:password_field]}_with_persistence=(value)
49
- self.#{options[:persistence_token_field]} = self.class.unique_token
52
+ reset_#{options[:persistence_token_field]}
50
53
  self.#{options[:password_field]}_without_persistence = value
51
54
  end
52
55
  alias_method_chain :#{options[:password_field]}=, :persistence
56
+
57
+ def reset_#{options[:persistence_token_field]}
58
+ self.#{options[:persistence_token_field]} = self.class.unique_token
59
+ end
60
+
61
+ def reset_#{options[:persistence_token_field]}!
62
+ reset_#{options[:persistence_token_field]}
63
+ save_without_session_maintenance(false)
64
+ end
65
+
66
+ def reset_#{options[:persistence_token_field]}?
67
+ #{options[:persistence_token_field]}.blank?
68
+ end
53
69
  end_eval
54
70
  end
55
71
  end
@@ -203,7 +203,7 @@ module Authlogic
203
203
  end
204
204
 
205
205
  # Allows you to set a unique identifier for your session, so that you can have more than 1 session at a time. A good example when this might be needed is when you want to have a normal user session
206
- # and a "secure" user session. The secure user session would be created only when they want to modify their billing information, or other sensative information. Similar to me.com. This requires 2
206
+ # and a "secure" user session. The secure user session would be created only when they want to modify their billing information, or other sensitive information. Similar to me.com. This requires 2
207
207
  # user sessions. Just use an id for the "secure" session and you should be good.
208
208
  #
209
209
  # You can set the id during initialization (see initialize for more information), or as an attribute:
@@ -357,7 +357,7 @@ module Authlogic
357
357
  return if respond_to?(login_field) # already created these methods
358
358
 
359
359
  self.class.class_eval <<-"end_eval", __FILE__, __LINE__
360
- alias_method :#{klass_name.underscore}, :record
360
+ alias_method :#{klass_name.underscore.split("/").last}, :record
361
361
 
362
362
  attr_reader :#{login_field}
363
363
 
@@ -44,7 +44,7 @@ module Authlogic # :nodoc:
44
44
 
45
45
  MAJOR = 1
46
46
  MINOR = 3
47
- TINY = 4
47
+ TINY = 5
48
48
 
49
49
  # The current version as a Version instance
50
50
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ module CryptoProviderTests
4
+ class AES256Test < ActiveSupport::TestCase
5
+ def test_encrypt
6
+ assert Authlogic::CryptoProviders::AES256.encrypt("mypass")
7
+ end
8
+
9
+ def test_matches
10
+ hash = Authlogic::CryptoProviders::AES256.encrypt("mypass")
11
+ assert Authlogic::CryptoProviders::AES256.matches?(hash, "mypass")
12
+ end
13
+ end
14
+ end
@@ -2,7 +2,7 @@ drew:
2
2
  company: binary_logic
3
3
  email: dgainor@binarylogic.com
4
4
  password_salt: <%= salt = Employee.unique_token %>
5
- crypted_password: "<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("drewrocks" + salt) %>"
5
+ crypted_password: '<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("drewrocks" + salt) %>'
6
6
  persistence_token: 5273d85ed156e9dbd6a7c1438d319ef8c8d41dd24368db6c222de11346c7b11e53ee08d45ecf619b1c1dc91233d22b372482b751b066d0a6f6f9bac42eacaabf
7
7
  first_name: Drew
8
8
  last_name: Gainor
@@ -11,7 +11,7 @@ jennifer:
11
11
  company: logic_over_data
12
12
  email: jjohnson@logicoverdata.com
13
13
  password_salt: <%= salt = Employee.unique_token %>
14
- crypted_password: "<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("jenniferocks" + salt) %>"
14
+ crypted_password: '<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("jenniferocks" + salt) %>'
15
15
  persistence_token: 2be52a8f741ad00056e6f94eb6844d5316527206da7a3a5e3d0e14d19499ef9fe4c47c89b87febb59a2b41a69edfb4733b6b79302040f3de83f297c6991c75a2
16
16
  first_name: Jennifer
17
17
  last_name: Johnson
@@ -36,7 +36,7 @@ module ORMAdaptersTests
36
36
  :validate_fields => true,
37
37
  :login_field => :login,
38
38
  :perishable_token_valid_for => 600,
39
- :password_field_validates_presence_of_options => {},
39
+ :password_field_validates_length_of_options => {},
40
40
  :password_field => :password,
41
41
  :validate_login_field => true,
42
42
  :email_field => :email,
@@ -44,7 +44,8 @@ module ORMAdaptersTests
44
44
  :password_field_validates_confirmation_of_options => {},
45
45
  :validate_email_field => true,
46
46
  :validation_options => {},
47
- :login_field_validation_options => {}
47
+ :login_field_validation_options => {},
48
+ :transition_from_crypto_provider => []
48
49
  }
49
50
  assert_equal default_config, User.acts_as_authentic_config
50
51
  end
@@ -76,6 +77,8 @@ module ORMAdaptersTests
76
77
  def test_transition_from_crypto_provider
77
78
  ben = users(:ben)
78
79
  convert_password_to(Authlogic::CryptoProviders::BCrypt, ben)
80
+ convert_password_to(Authlogic::CryptoProviders::Sha1, ben, [Authlogic::CryptoProviders::Sha512, Authlogic::CryptoProviders::BCrypt])
81
+ convert_password_to(Authlogic::CryptoProviders::Sha512, ben, [Authlogic::CryptoProviders::Sha1, Authlogic::CryptoProviders::BCrypt])
79
82
  end
80
83
 
81
84
  def test_act_like_restful_authentication
@@ -97,7 +100,7 @@ module ORMAdaptersTests
97
100
  def test_transition_from_restful_authentication
98
101
  User.acts_as_authentic(:transition_from_restful_authentication => true)
99
102
  assert_equal Authlogic::CryptoProviders::Sha512, User.acts_as_authentic_config[:crypto_provider]
100
- assert_equal Authlogic::CryptoProviders::Sha1, User.acts_as_authentic_config[:transition_from_crypto_provider]
103
+ assert_equal [Authlogic::CryptoProviders::Sha1], User.acts_as_authentic_config[:transition_from_crypto_provider]
101
104
  end
102
105
 
103
106
  private
@@ -109,8 +112,9 @@ module ORMAdaptersTests
109
112
  User.acts_as_authentic @default_configuration
110
113
  end
111
114
 
112
- def convert_password_to(crypto_provider, *records)
113
- User.acts_as_authentic(:crypto_provider => crypto_provider, :transition_from_crypto_provider => Authlogic::CryptoProviders::Sha512)
115
+ def convert_password_to(crypto_provider, records, from_crypto_providers = Authlogic::CryptoProviders::Sha512)
116
+ records = [records] unless records.is_a?(Array)
117
+ User.acts_as_authentic(:crypto_provider => crypto_provider, :transition_from_crypto_provider => from_crypto_providers)
114
118
  records.each do |record|
115
119
  old_hash = record.crypted_password
116
120
  assert record.valid_password?(password_for(record))
@@ -4,7 +4,6 @@ require "ruby-debug"
4
4
  require "active_record"
5
5
  require 'active_record/fixtures'
6
6
  require File.dirname(__FILE__) + '/../lib/authlogic' unless defined?(Authlogic)
7
- require File.dirname(__FILE__) + '/libs/aes128_crypto_provider'
8
7
  require File.dirname(__FILE__) + '/libs/mock_request'
9
8
  require File.dirname(__FILE__) + '/libs/mock_cookie_jar'
10
9
  require File.dirname(__FILE__) + '/libs/mock_controller'
@@ -94,8 +93,10 @@ class User < ActiveRecord::Base
94
93
  has_and_belongs_to_many :projects
95
94
  end
96
95
 
96
+ Authlogic::CryptoProviders::AES256.key = "myafdsfddddddddddddddddddddddddddddddddddddddddddddddd"
97
+
97
98
  class Employee < ActiveRecord::Base
98
- acts_as_authentic :crypto_provider => AES128CryptoProvider
99
+ acts_as_authentic :crypto_provider => Authlogic::CryptoProviders::AES256
99
100
  belongs_to :company
100
101
  end
101
102
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-24 00:00:00 -05:00
12
+ date: 2008-11-30 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,7 @@ extra_rdoc_files:
43
43
  - lib/authlogic/controller_adapters/abstract_adapter.rb
44
44
  - lib/authlogic/controller_adapters/merb_adapter.rb
45
45
  - lib/authlogic/controller_adapters/rails_adapter.rb
46
+ - lib/authlogic/crypto_providers/aes256.rb
46
47
  - lib/authlogic/crypto_providers/bcrypt.rb
47
48
  - lib/authlogic/crypto_providers/sha1.rb
48
49
  - lib/authlogic/crypto_providers/sha512.rb
@@ -75,6 +76,7 @@ files:
75
76
  - lib/authlogic/controller_adapters/abstract_adapter.rb
76
77
  - lib/authlogic/controller_adapters/merb_adapter.rb
77
78
  - lib/authlogic/controller_adapters/rails_adapter.rb
79
+ - lib/authlogic/crypto_providers/aes256.rb
78
80
  - lib/authlogic/crypto_providers/bcrypt.rb
79
81
  - lib/authlogic/crypto_providers/sha1.rb
80
82
  - lib/authlogic/crypto_providers/sha512.rb
@@ -105,11 +107,14 @@ files:
105
107
  - Rakefile
106
108
  - README.rdoc
107
109
  - shoulda_macros/authlogic.rb
110
+ - test/crypto_provider_tests/aes256_test.rb
111
+ - test/crypto_provider_tests/bcrypt_test.rb
112
+ - test/crypto_provider_tests/sha1_test.rb
113
+ - test/crypto_provider_tests/sha512_test.rb
108
114
  - test/fixtures/companies.yml
109
115
  - test/fixtures/employees.yml
110
116
  - test/fixtures/projects.yml
111
117
  - test/fixtures/users.yml
112
- - test/libs/aes128_crypto_provider.rb
113
118
  - test/libs/mock_controller.rb
114
119
  - test/libs/mock_cookie_jar.rb
115
120
  - test/libs/mock_request.rb
@@ -165,6 +170,7 @@ signing_key:
165
170
  specification_version: 2
166
171
  summary: A clean, simple, and unobtrusive ruby authentication solution.
167
172
  test_files:
173
+ - test/crypto_provider_tests/aes256_test.rb
168
174
  - test/crypto_provider_tests/bcrypt_test.rb
169
175
  - test/crypto_provider_tests/sha1_test.rb
170
176
  - test/crypto_provider_tests/sha512_test.rb
@@ -1,17 +0,0 @@
1
- require "ezcrypto"
2
-
3
- class AES128CryptoProvider
4
- class << self
5
- def encrypt(*tokens)
6
- [key.encrypt(tokens.join)].pack("m").chomp
7
- end
8
-
9
- def matches?(crypted, *tokens)
10
- key.decrypt(crypted.unpack("m").first) == tokens.join
11
- end
12
-
13
- def key
14
- EzCrypto::Key.with_password "master_key", "some_salt"
15
- end
16
- end
17
- end