Skip to content

Commit

Permalink
Use SecureRandom if it is available.
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Johnson <bjohnson@binarylogic.com>
  • Loading branch information
thedarkone authored and binarylogic committed Feb 27, 2009
1 parent b7942be commit 844ba84
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 5 deletions.
1 change: 1 addition & 0 deletions lib/authlogic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require File.dirname(__FILE__) + "/authlogic/version"
require File.dirname(__FILE__) + "/authlogic/i18n"
require File.dirname(__FILE__) + "/authlogic/random"

require File.dirname(__FILE__) + "/authlogic/controller_adapters/abstract_adapter"
require File.dirname(__FILE__) + "/authlogic/controller_adapters/rails_adapter" if defined?(Rails)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ def acts_as_authentic_with_credentials(options = {})

class_eval <<-"end_eval", __FILE__, __LINE__
def self.friendly_unique_token
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(20) { |i| newpass << chars[rand(chars.size-1)] }
newpass
Authlogic::Random.friendly_token
end
def #{options[:password_field]}=(pass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def forget_all!

class_eval <<-"end_eval", __FILE__, __LINE__
def self.unique_token
Authlogic::CryptoProviders::Sha512.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
Authlogic::Random.hex_token
end
def forget!
Expand Down
31 changes: 31 additions & 0 deletions lib/authlogic/random.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Authlogic
module Random
extend self

SecureRandom = (defined?(::SecureRandom) && ::SecureRandom) || (defined?(::ActiveSupport::SecureRandom) && ::ActiveSupport::SecureRandom)

if SecureRandom
def hex_token
SecureRandom.hex(64)
end

def friendly_token
# use base64url as defined by RFC4648
SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
end
else
def hex_token
Authlogic::CryptoProviders::Sha512.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
end

FRIENDLY_CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a

def friendly_token
newpass = ""
1.upto(20) { |i| newpass << FRIENDLY_CHARS[rand(FRIENDLY_CHARS.size-1)] }
newpass
end
end

end
end
51 changes: 51 additions & 0 deletions test/random_tests/random_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require File.dirname(__FILE__) + '/../test_helper.rb'

module RandomTests
class RandomTest < ActiveSupport::TestCase
def test_random_tokens_have_consisten_length
with_any_random do
assert_equal 128, Authlogic::Random.hex_token.length
assert_equal 20, Authlogic::Random.friendly_token.length
end
end

def test_random_tokens_are_indeed_random
# this might fail if you are *really* unlucky :)
with_any_random do
assert_not_equal Authlogic::Random.hex_token, Authlogic::Random.hex_token
assert_not_equal Authlogic::Random.friendly_token, Authlogic::Random.friendly_token
end
end

private
def with_any_random(&block)
[true, false].each {|val| with_secure_random_enabled(val, &block)}
end

def with_secure_random_enabled(enabled = true)
# can't really test SecureRandom if we don't have an implementation
return if enabled && !Authlogic::Random::SecureRandom

current_sec_rand = Authlogic::Random::SecureRandom
reload_authlogic_with_sec_random!(current_sec_rand, enabled)

yield
ensure
reload_authlogic_with_sec_random!(current_sec_rand)
end

def reload_authlogic_with_sec_random!(secure_random, enabled = true)
silence_warnings do
secure_random.parent.const_set(secure_random.name.sub("#{secure_random.parent}::", ''), enabled ? secure_random : nil)
load(File.dirname(__FILE__) + '/../../lib/authlogic/random.rb')
end
end

def silence_warnings
old_verbose, $VERBOSE = $VERBOSE, nil
yield
ensure
$VERBOSE = old_verbose
end
end
end

0 comments on commit 844ba84

Please sign in to comment.