Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85832960
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex
index 90bd07b91..a3317f432 100644
--- a/lib/pleroma/plugs/authentication_plug.ex
+++ b/lib/pleroma/plugs/authentication_plug.ex
@@ -1,51 +1,59 @@
defmodule Pleroma.Plugs.AuthenticationPlug do
import Plug.Conn
def init(options) do
options
end
def call(conn, opts) do
with {:ok, username, password} <- decode_header(conn),
{:ok, user} <- opts[:fetcher].(username),
- {:ok, verified_user} <- verify(user, password)
+ saved_user_id <- get_session(conn, :user_id),
+ {:ok, verified_user} <- verify(user, password, saved_user_id)
do
- conn |> assign(:user, verified_user)
+ conn
+ |> assign(:user, verified_user)
+ |> put_session(:user_id, verified_user.id)
else
_ -> conn |> halt_or_continue(opts)
end
end
- defp verify(nil, _password) do
+ # Short-circuit if we have a cookie with the id for the given user.
+ defp verify(%{id: id} = user, _password, id) do
+ {:ok, user}
+ end
+
+ defp verify(nil, _password, _user_id) do
Comeonin.Pbkdf2.dummy_checkpw
:error
end
- defp verify(user, password) do
+ defp verify(user, password, _user_id) do
if Comeonin.Pbkdf2.checkpw(password, user.password_hash) do
{:ok, user}
else
:error
end
end
defp decode_header(conn) do
with ["Basic " <> header] <- get_req_header(conn, "authorization"),
{:ok, userinfo} <- Base.decode64(header),
[username, password] <- String.split(userinfo, ":")
do
{ :ok, username, password }
end
end
defp halt_or_continue(conn, %{optional: true}) do
conn |> assign(:user, nil)
end
defp halt_or_continue(conn, _) do
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Poison.encode!(%{error: "Invalid credentials."}))
|> halt
end
end
diff --git a/test/plugs/authentication_plug_test.exs b/test/plugs/authentication_plug_test.exs
index 3f2f769e7..6f1568ec3 100644
--- a/test/plugs/authentication_plug_test.exs
+++ b/test/plugs/authentication_plug_test.exs
@@ -1,110 +1,153 @@
defmodule Pleroma.Plugs.AuthenticationPlugTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Plugs.AuthenticationPlug
defp fetch_nil(_name) do
{:ok, nil}
end
@user %{
id: 1,
name: "dude",
password_hash: Comeonin.Pbkdf2.hashpwsalt("guy")
}
+ @session_opts [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
defp fetch_user(_name) do
{:ok, @user}
end
defp basic_auth_enc(username, password) do
"Basic " <> Base.encode64("#{username}:#{password}")
end
describe "without an authorization header" do
test "it halts the application" do
- conn = build_conn() |> AuthenticationPlug.call(%{})
+ conn = build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
+ |> AuthenticationPlug.call(%{})
assert conn.status == 403
assert conn.halted == true
end
test "it assigns a nil user if the 'optional' option is used" do
- conn = build_conn() |> AuthenticationPlug.call(%{optional: true})
+ conn = build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
+ |> AuthenticationPlug.call(%{optional: true})
assert %{ user: nil } == conn.assigns
end
end
describe "with an authorization header for a nonexisting user" do
test "it halts the application" do
conn =
build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
|> AuthenticationPlug.call(%{fetcher: &fetch_nil/1})
assert conn.status == 403
assert conn.halted == true
end
test "it assigns a nil user if the 'optional' option is used" do
conn =
build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
|> AuthenticationPlug.call(%{optional: true, fetcher: &fetch_nil/1 })
assert %{ user: nil } == conn.assigns
end
end
describe "with an incorrect authorization header for a enxisting user" do
test "it halts the application" do
opts = %{
fetcher: &fetch_user/1
}
header = basic_auth_enc("dude", "man")
conn =
build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
|> put_req_header("authorization", header)
|> AuthenticationPlug.call(opts)
assert conn.status == 403
assert conn.halted == true
end
test "it assigns a nil user if the 'optional' option is used" do
opts = %{
optional: true,
fetcher: &fetch_user/1
}
header = basic_auth_enc("dude", "man")
conn =
build_conn()
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
|> put_req_header("authorization", header)
|> AuthenticationPlug.call(opts)
assert %{ user: nil } == conn.assigns
end
end
describe "with a correct authorization header for an existing user" do
- test "it assigns the user" do
+ test "it assigns the user", %{conn: conn} do
opts = %{
optional: true,
fetcher: &fetch_user/1
}
header = basic_auth_enc("dude", "guy")
- conn =
- build_conn()
+ conn = conn
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
+ |> put_req_header("authorization", header)
+ |> AuthenticationPlug.call(opts)
+
+ assert %{ user: @user } == conn.assigns
+ assert get_session(conn, :user_id) == @user.id
+ assert conn.halted == false
+ end
+ end
+ describe "with a user_id in the session for an existing user" do
+ test "it assigns the user", %{conn: conn} do
+ opts = %{
+ optional: true,
+ fetcher: &fetch_user/1
+ }
+
+ header = basic_auth_enc("dude", "THIS IS WRONG")
+
+ conn = conn
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session
+ |> put_session(:user_id, @user.id)
|> put_req_header("authorization", header)
|> AuthenticationPlug.call(opts)
assert %{ user: @user } == conn.assigns
+ assert get_session(conn, :user_id) == @user.id
assert conn.halted == false
end
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 2, 9:34 AM (2 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1804235
Default Alt Text
(6 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline