users: refactor login and authentication logic.

* Make authentication methods into User instance methods instead of
  class methods.
* Fix API key authentication to use a secure string comparison. Fixes a
  hypothetical (unlikely to be exploitable) timing attack.
* Move login logic from SessionCreator to SessionLoader.
This commit is contained in:
evazion
2020-03-25 03:41:27 -05:00
parent 64af957031
commit b2cf765d6d
14 changed files with 68 additions and 100 deletions

View File

@@ -18,8 +18,8 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
put_auth user_password_path(@user), @user, params: { user: { old_password: "12345", password: "abcde", password_confirmation: "abcde" } }
assert_redirected_to @user
assert_equal(nil, User.authenticate(@user.name, "12345"))
assert_equal(@user, User.authenticate(@user.name, "abcde"))
assert_equal(false, @user.reload.authenticate_password("12345"))
assert_equal(@user, @user.authenticate_password("abcde"))
end
should "update the password when given a valid login key" do
@@ -27,24 +27,24 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
put_auth user_password_path(@user), @user, params: { user: { password: "abcde", password_confirmation: "abcde", signed_user_id: signed_user_id } }
assert_redirected_to @user
assert_equal(nil, User.authenticate(@user.name, "12345"))
assert_equal(@user, User.authenticate(@user.name, "abcde"))
assert_equal(false, @user.reload.authenticate_password("12345"))
assert_equal(@user, @user.authenticate_password("abcde"))
end
should "not update the password when given an invalid old password" do
put_auth user_password_path(@user), @user, params: { user: { old_password: "3qoirjqe", password: "abcde", password_confirmation: "abcde" } }
assert_response :success
assert_equal(@user, User.authenticate(@user.name, "12345"))
assert_equal(nil, User.authenticate(@user.name, "abcde"))
assert_equal(@user, @user.reload.authenticate_password("12345"))
assert_equal(false, @user.authenticate_password("abcde"))
end
should "not update the password when password confirmation fails for the new password" do
put_auth user_password_path(@user), @user, params: { user: { old_password: "12345", password: "abcde", password_confirmation: "qerogijqe" } }
assert_response :success
assert_equal(@user, User.authenticate(@user.name, "12345"))
assert_equal(nil, User.authenticate(@user.name, "abcde"))
assert_equal(@user, @user.reload.authenticate_password("12345"))
assert_equal(false, @user.authenticate_password("abcde"))
end
end
end