@@ -14,7 +14,17 @@ defmodule Pleroma.Plugs.AuthenticationPlug do | |||||
{:ok, user} <- opts[:fetcher].(username), | {:ok, user} <- opts[:fetcher].(username), | ||||
false <- !!user.info["deactivated"], | false <- !!user.info["deactivated"], | ||||
saved_user_id <- get_session(conn, :user_id), | saved_user_id <- get_session(conn, :user_id), | ||||
legacy_password <- String.starts_with?(user.password_hash, "$6$"), | |||||
update_legacy_password <- | |||||
!(Map.has_key?(opts, :update_legacy_password) && opts[:update_legacy_password] == false), | |||||
{:ok, verified_user} <- verify(user, password, saved_user_id) do | {:ok, verified_user} <- verify(user, password, saved_user_id) do | ||||
if legacy_password and update_legacy_password do | |||||
User.reset_password(verified_user, %{ | |||||
:password => password, | |||||
:password_confirmation => password | |||||
}) | |||||
end | |||||
conn | conn | ||||
|> assign(:user, verified_user) | |> assign(:user, verified_user) | ||||
|> put_session(:user_id, verified_user.id) | |> put_session(:user_id, verified_user.id) | ||||
@@ -34,7 +44,18 @@ defmodule Pleroma.Plugs.AuthenticationPlug do | |||||
end | end | ||||
defp verify(user, password, _user_id) do | defp verify(user, password, _user_id) do | ||||
if Pbkdf2.checkpw(password, user.password_hash) do | |||||
is_legacy = String.starts_with?(user.password_hash, "$6$") | |||||
valid = | |||||
cond do | |||||
is_legacy -> | |||||
:crypt.crypt(password, user.password_hash) == user.password_hash | |||||
true -> | |||||
Pbkdf2.checkpw(password, user.password_hash) | |||||
end | |||||
if valid do | |||||
{:ok, user} | {:ok, user} | ||||
else | else | ||||
:error | :error | ||||
@@ -50,7 +50,8 @@ defmodule Pleroma.Mixfile do | |||||
{:ex_aws_s3, "~> 2.0"}, | {:ex_aws_s3, "~> 2.0"}, | ||||
{:ex_machina, "~> 2.2", only: :test}, | {:ex_machina, "~> 2.2", only: :test}, | ||||
{:credo, "~> 0.9.3", only: [:dev, :test]}, | {:credo, "~> 0.9.3", only: [:dev, :test]}, | ||||
{:mock, "~> 0.3.1", only: :test} | |||||
{:mock, "~> 0.3.1", only: :test}, | |||||
{:crypt, git: "https://github.com/msantos/crypt"} | |||||
] | ] | ||||
end | end | ||||
@@ -21,6 +21,13 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||||
info: %{"deactivated" => true} | info: %{"deactivated" => true} | ||||
} | } | ||||
@legacy %User{ | |||||
id: 1, | |||||
name: "dude", | |||||
password_hash: | |||||
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" | |||||
} | |||||
@session_opts [ | @session_opts [ | ||||
store: :cookie, | store: :cookie, | ||||
key: "_test", | key: "_test", | ||||
@@ -139,6 +146,27 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||||
assert get_session(conn, :user_id) == @user.id | assert get_session(conn, :user_id) == @user.id | ||||
assert conn.halted == false | assert conn.halted == false | ||||
end | end | ||||
test "it assigns legacy user", %{conn: conn} do | |||||
opts = %{ | |||||
optional: true, | |||||
fetcher: fn _ -> {:ok, @legacy} end, | |||||
update_legacy_password: false | |||||
} | |||||
header = basic_auth_enc("dude", "password") | |||||
conn = | |||||
conn | |||||
|> Plug.Session.call(Plug.Session.init(@session_opts)) | |||||
|> fetch_session | |||||
|> put_req_header("authorization", header) | |||||
|> AuthenticationPlug.call(opts) | |||||
assert %{user: @legacy} == conn.assigns | |||||
assert get_session(conn, :user_id) == @legacy.id | |||||
assert conn.halted == false | |||||
end | |||||
end | end | ||||
describe "with a correct authorization header for an deactiviated user" do | describe "with a correct authorization header for an deactiviated user" do | ||||