end
end
- user = nil if user and not PasswordHash.check(user.pass_crypt, user.pass_salt, options[:password])
+ if user and PasswordHash.check(user.pass_crypt, user.pass_salt, options[:password])
+ if PasswordHash.upgrade?(user.pass_crypt, user.pass_salt)
+ user.pass_crypt, user.pass_salt = PasswordHash.create(options[:password])
+ user.save
+ end
+ else
+ user = nil
+ end
elsif options[:token]
token = UserToken.find_by_token(options[:token])
user = token.user if token
return hash == candidate
end
+ def self.upgrade?(hash, salt)
+ if salt.nil?
+ return true
+ elsif salt =~ /!/
+ algorithm, iterations, salt = salt.split("!")
+ return true if Base64.strict_decode64(salt).length != SALT_BYTE_SIZE
+ return true if Base64.strict_decode64(hash).length != HASH_BYTE_SIZE
+ return true if iterations.to_i != PBKDF2_ITERATIONS
+ return true if algorithm != DIGEST_ALGORITHM
+ else
+ return true
+ end
+
+ return false
+ end
+
private
def self.hash(password, salt, iterations, size, algorithm)
def test_md5_without_salt
assert_equal true, PasswordHash.check("5f4dcc3b5aa765d61d8327deb882cf99", nil, "password")
assert_equal false, PasswordHash.check("5f4dcc3b5aa765d61d8327deb882cf99", nil, "wrong")
+ assert_equal true, PasswordHash.upgrade?("5f4dcc3b5aa765d61d8327deb882cf99", nil)
end
def test_md5_with_salt
assert_equal true, PasswordHash.check("67a1e09bb1f83f5007dc119c14d663aa", "salt", "password")
assert_equal false, PasswordHash.check("67a1e09bb1f83f5007dc119c14d663aa", "salt", "wrong")
assert_equal false, PasswordHash.check("67a1e09bb1f83f5007dc119c14d663aa", "wrong", "password")
+ assert_equal true, PasswordHash.upgrade?("67a1e09bb1f83f5007dc119c14d663aa", "salt")
end
def test_default
assert_equal false, PasswordHash.check(hash1, salt1, "wrong")
assert_equal true, PasswordHash.check(hash2, salt2, "password")
assert_equal false, PasswordHash.check(hash2, salt2, "wrong")
+ assert_equal false, PasswordHash.upgrade?(hash1, salt1)
+ assert_equal false, PasswordHash.upgrade?(hash2, salt2)
end
end