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.
- data/CHANGELOG.rdoc +9 -0
- data/Manifest +5 -1
- data/README.rdoc +68 -35
- data/authlogic.gemspec +5 -5
- data/lib/authlogic.rb +1 -0
- data/lib/authlogic/controller_adapters/merb_adapter.rb +2 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +2 -0
- data/lib/authlogic/crypto_providers/aes256.rb +45 -0
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb +5 -3
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb +13 -14
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb +17 -1
- data/lib/authlogic/session/base.rb +2 -2
- data/lib/authlogic/version.rb +1 -1
- data/test/crypto_provider_tests/aes256_test.rb +14 -0
- data/test/fixtures/employees.yml +2 -2
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb +9 -5
- data/test/test_helper.rb +3 -2
- metadata +9 -3
- data/test/libs/aes128_crypto_provider.rb +0 -17
data/CHANGELOG.rdoc
CHANGED
@@ -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
|
data/README.rdoc
CHANGED
@@ -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
|
-
|
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
|
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
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
data/authlogic.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{authlogic}
|
5
|
-
s.version = "1.3.
|
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-
|
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/
|
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
|
data/lib/authlogic.rb
CHANGED
@@ -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>
|
128
|
-
# These options are applied to the
|
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 ? [:
|
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[:
|
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
|
-
|
44
|
-
validates_confirmation_of options[:password_field], options[:password_field_validates_confirmation_of_options].merge(:if => "#{options[:
|
45
|
-
validates_presence_of "#{options[:password_field]}_confirmation", :if => "#{options[:
|
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]}
|
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 =
|
79
|
-
|
80
|
-
|
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
|
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
|
-
|
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
|
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
|
|
data/lib/authlogic/version.rb
CHANGED
@@ -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
|
data/test/fixtures/employees.yml
CHANGED
@@ -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:
|
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:
|
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
|
data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
CHANGED
@@ -36,7 +36,7 @@ module ORMAdaptersTests
|
|
36
36
|
:validate_fields => true,
|
37
37
|
:login_field => :login,
|
38
38
|
:perishable_token_valid_for => 600,
|
39
|
-
:
|
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,
|
113
|
-
|
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))
|
data/test/test_helper.rb
CHANGED
@@ -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 =>
|
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
|
+
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-
|
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
|