summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/dev.md4
-rw-r--r--lib/pleroma/helpers/auth_helper.ex25
-rw-r--r--lib/pleroma/web/o_auth/o_auth_controller.ex10
-rw-r--r--lib/pleroma/web/o_auth/token.ex8
-rw-r--r--lib/pleroma/web/plugs/admin_secret_authentication_plug.ex4
-rw-r--r--lib/pleroma/web/plugs/authentication_plug.ex63
-rw-r--r--lib/pleroma/web/plugs/basic_auth_decoder_plug.ex6
-rw-r--r--lib/pleroma/web/plugs/ensure_user_key_plug.ex5
-rw-r--r--lib/pleroma/web/plugs/legacy_authentication_plug.ex41
-rw-r--r--lib/pleroma/web/plugs/o_auth_plug.ex92
-rw-r--r--lib/pleroma/web/plugs/session_authentication_plug.ex21
-rw-r--r--lib/pleroma/web/plugs/set_user_session_id_plug.ex8
-rw-r--r--lib/pleroma/web/plugs/user_enabled_plug.ex9
-rw-r--r--lib/pleroma/web/plugs/user_fetcher_plug.ex6
-rw-r--r--lib/pleroma/web/router.ex13
-rw-r--r--test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs2
-rw-r--r--test/pleroma/web/plugs/authentication_plug_test.exs3
-rw-r--r--test/pleroma/web/plugs/legacy_authentication_plug_test.exs82
-rw-r--r--test/pleroma/web/plugs/o_auth_plug_test.exs99
-rw-r--r--test/pleroma/web/plugs/session_authentication_plug_test.exs63
-rw-r--r--test/pleroma/web/plugs/set_user_session_id_plug_test.exs19
21 files changed, 233 insertions, 350 deletions
diff --git a/docs/dev.md b/docs/dev.md
index aa89a941f..765380a58 100644
--- a/docs/dev.md
+++ b/docs/dev.md
@@ -14,9 +14,9 @@ This document contains notes and guidelines for Pleroma developers.
For `:api` pipeline routes, it'll be verified whether `OAuthScopesPlug` was called or explicitly skipped, and if it was not then auth information will be dropped for request. Then `EnsurePublicOrAuthenticatedPlug` will be called to ensure that either the instance is not private or user is authenticated (unless explicitly skipped). Such automated checks help to prevent human errors and result in higher security / privacy for users.
-## [HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization)
+## Non-OAuth authentication
-* With HTTP Basic Auth, OAuth scopes check is _not_ performed for any action (since password is provided during the auth, requester is able to obtain a token with full permissions anyways). `Pleroma.Web.Plugs.AuthenticationPlug` and `Pleroma.Web.Plugs.LegacyAuthenticationPlug` both call `Pleroma.Web.Plugs.OAuthScopesPlug.skip_plug(conn)` when password is provided.
+* With non-OAuth authentication ([HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) or HTTP header- or params-provided auth), OAuth scopes check is _not_ performed for any action (since password is provided during the auth, requester is able to obtain a token with full permissions anyways); auth plugs invoke `Pleroma.Helpers.AuthHelper.skip_oauth(conn)` in this case.
## Auth-related configuration, OAuth consumer mode etc.
diff --git a/lib/pleroma/helpers/auth_helper.ex b/lib/pleroma/helpers/auth_helper.ex
new file mode 100644
index 000000000..878fec346
--- /dev/null
+++ b/lib/pleroma/helpers/auth_helper.ex
@@ -0,0 +1,25 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Helpers.AuthHelper do
+ alias Pleroma.Web.Plugs.OAuthScopesPlug
+
+ import Plug.Conn
+
+ @doc """
+ Skips OAuth permissions (scopes) checks, assigns nil `:token`.
+ Intended to be used with explicit authentication and only when OAuth token cannot be determined.
+ """
+ def skip_oauth(conn) do
+ conn
+ |> assign(:token, nil)
+ |> OAuthScopesPlug.skip_plug()
+ end
+
+ def drop_auth_info(conn) do
+ conn
+ |> assign(:user, nil)
+ |> assign(:token, nil)
+ end
+end
diff --git a/lib/pleroma/web/o_auth/o_auth_controller.ex b/lib/pleroma/web/o_auth/o_auth_controller.ex
index d2f9d1ceb..83a25907d 100644
--- a/lib/pleroma/web/o_auth/o_auth_controller.ex
+++ b/lib/pleroma/web/o_auth/o_auth_controller.ex
@@ -363,7 +363,15 @@ defmodule Pleroma.Web.OAuth.OAuthController do
def token_revoke(%Plug.Conn{} = conn, %{"token" => _token} = params) do
with {:ok, app} <- Token.Utils.fetch_app(conn),
- {:ok, _token} <- RevokeToken.revoke(app, params) do
+ {:ok, %Token{} = oauth_token} <- RevokeToken.revoke(app, params) do
+ conn =
+ with session_token = get_session(conn, :oauth_token),
+ %Token{token: ^session_token} <- oauth_token do
+ delete_session(conn, :oauth_token)
+ else
+ _ -> conn
+ end
+
json(conn, %{})
else
_error ->
diff --git a/lib/pleroma/web/o_auth/token.ex b/lib/pleroma/web/o_auth/token.ex
index de37998f2..9170a7ec7 100644
--- a/lib/pleroma/web/o_auth/token.ex
+++ b/lib/pleroma/web/o_auth/token.ex
@@ -27,6 +27,14 @@ defmodule Pleroma.Web.OAuth.Token do
timestamps()
end
+ @doc "Gets token by unique access token"
+ @spec get_by_token(String.t()) :: {:ok, t()} | {:error, :not_found}
+ def get_by_token(token) do
+ token
+ |> Query.get_by_token()
+ |> Repo.find_resource()
+ end
+
@doc "Gets token for app by access token"
@spec get_by_token(App.t(), String.t()) :: {:ok, t()} | {:error, :not_found}
def get_by_token(%App{id: app_id} = _app, token) do
diff --git a/lib/pleroma/web/plugs/admin_secret_authentication_plug.ex b/lib/pleroma/web/plugs/admin_secret_authentication_plug.ex
index d7d4e4092..ff49801f4 100644
--- a/lib/pleroma/web/plugs/admin_secret_authentication_plug.ex
+++ b/lib/pleroma/web/plugs/admin_secret_authentication_plug.ex
@@ -5,8 +5,8 @@
defmodule Pleroma.Web.Plugs.AdminSecretAuthenticationPlug do
import Plug.Conn
+ alias Pleroma.Helpers.AuthHelper
alias Pleroma.User
- alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.Plugs.RateLimiter
def init(options) do
@@ -51,7 +51,7 @@ defmodule Pleroma.Web.Plugs.AdminSecretAuthenticationPlug do
defp assign_admin_user(conn) do
conn
|> assign(:user, %User{is_admin: true})
- |> OAuthScopesPlug.skip_plug()
+ |> AuthHelper.skip_oauth()
end
defp handle_bad_token(conn) do
diff --git a/lib/pleroma/web/plugs/authentication_plug.ex b/lib/pleroma/web/plugs/authentication_plug.ex
index e2a8b1b69..a7b8a9bfe 100644
--- a/lib/pleroma/web/plugs/authentication_plug.ex
+++ b/lib/pleroma/web/plugs/authentication_plug.ex
@@ -3,6 +3,9 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.AuthenticationPlug do
+ @moduledoc "Password authentication plug."
+
+ alias Pleroma.Helpers.AuthHelper
alias Pleroma.User
import Plug.Conn
@@ -11,6 +14,30 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlug do
def init(options), do: options
+ def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
+
+ def call(
+ %{
+ assigns: %{
+ auth_user: %{password_hash: password_hash} = auth_user,
+ auth_credentials: %{password: password}
+ }
+ } = conn,
+ _
+ ) do
+ if checkpw(password, password_hash) do
+ {:ok, auth_user} = maybe_update_password(auth_user, password)
+
+ conn
+ |> assign(:user, auth_user)
+ |> AuthHelper.skip_oauth()
+ else
+ conn
+ end
+ end
+
+ def call(conn, _), do: conn
+
def checkpw(password, "$6" <> _ = password_hash) do
:crypt.crypt(password, password_hash) == password_hash
end
@@ -40,40 +67,6 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlug do
def maybe_update_password(user, _), do: {:ok, user}
defp do_update_password(user, password) do
- user
- |> User.password_update_changeset(%{
- "password" => password,
- "password_confirmation" => password
- })
- |> Pleroma.Repo.update()
+ User.reset_password(user, %{password: password, password_confirmation: password})
end
-
- def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
-
- def call(
- %{
- assigns: %{
- auth_user: %{password_hash: password_hash} = auth_user,
- auth_credentials: %{password: password}
- }
- } = conn,
- _
- ) do
- if checkpw(password, password_hash) do
- {:ok, auth_user} = maybe_update_password(auth_user, password)
-
- conn
- |> assign(:user, auth_user)
- |> Pleroma.Web.Plugs.OAuthScopesPlug.skip_plug()
- else
- conn
- end
- end
-
- def call(%{assigns: %{auth_credentials: %{password: _}}} = conn, _) do
- Pbkdf2.no_user_verify()
- conn
- end
-
- def call(conn, _), do: conn
end
diff --git a/lib/pleroma/web/plugs/basic_auth_decoder_plug.ex b/lib/pleroma/web/plugs/basic_auth_decoder_plug.ex
index 4dadfb000..97529aedb 100644
--- a/lib/pleroma/web/plugs/basic_auth_decoder_plug.ex
+++ b/lib/pleroma/web/plugs/basic_auth_decoder_plug.ex
@@ -3,6 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.BasicAuthDecoderPlug do
+ @moduledoc """
+ Decodes HTTP Basic Auth information and assigns `:auth_credentials`.
+
+ NOTE: no checks are performed at this step, auth_credentials/username could be easily faked.
+ """
+
import Plug.Conn
def init(options) do
diff --git a/lib/pleroma/web/plugs/ensure_user_key_plug.ex b/lib/pleroma/web/plugs/ensure_user_key_plug.ex
index 70d3091f0..31608dbbf 100644
--- a/lib/pleroma/web/plugs/ensure_user_key_plug.ex
+++ b/lib/pleroma/web/plugs/ensure_user_key_plug.ex
@@ -5,6 +5,8 @@
defmodule Pleroma.Web.Plugs.EnsureUserKeyPlug do
import Plug.Conn
+ @moduledoc "Ensures `conn.assigns.user` is initialized."
+
def init(opts) do
opts
end
@@ -12,7 +14,6 @@ defmodule Pleroma.Web.Plugs.EnsureUserKeyPlug do
def call(%{assigns: %{user: _}} = conn, _), do: conn
def call(conn, _) do
- conn
- |> assign(:user, nil)
+ assign(conn, :user, nil)
end
end
diff --git a/lib/pleroma/web/plugs/legacy_authentication_plug.ex b/lib/pleroma/web/plugs/legacy_authentication_plug.ex
deleted file mode 100644
index 2a54d0b59..000000000
--- a/lib/pleroma/web/plugs/legacy_authentication_plug.ex
+++ /dev/null
@@ -1,41 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Plugs.LegacyAuthenticationPlug do
- import Plug.Conn
-
- alias Pleroma.User
-
- def init(options) do
- options
- end
-
- def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
-
- def call(
- %{
- assigns: %{
- auth_user: %{password_hash: "$6$" <> _ = password_hash} = auth_user,
- auth_credentials: %{password: password}
- }
- } = conn,
- _
- ) do
- with ^password_hash <- :crypt.crypt(password, password_hash),
- {:ok, user} <-
- User.reset_password(auth_user, %{password: password, password_confirmation: password}) do
- conn
- |> assign(:auth_user, user)
- |> assign(:user, user)
- |> Pleroma.Web.Plugs.OAuthScopesPlug.skip_plug()
- else
- _ ->
- conn
- end
- end
-
- def call(conn, _) do
- conn
- end
-end
diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex
index c7b58d90f..a3b7d42f7 100644
--- a/lib/pleroma/web/plugs/o_auth_plug.ex
+++ b/lib/pleroma/web/plugs/o_auth_plug.ex
@@ -3,6 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.OAuthPlug do
+ @moduledoc "Performs OAuth authentication by token from params / headers / cookies."
+
import Plug.Conn
import Ecto.Query
@@ -17,45 +19,26 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
- def call(%{params: %{"access_token" => access_token}} = conn, _) do
- with {:ok, user, token_record} <- fetch_user_and_token(access_token) do
- conn
- |> assign(:token, token_record)
- |> assign(:user, user)
- else
- _ ->
- # token found, but maybe only with app
- with {:ok, app, token_record} <- fetch_app_and_token(access_token) do
- conn
- |> assign(:token, token_record)
- |> assign(:app, app)
- else
- _ -> conn
- end
- end
- end
-
def call(conn, _) do
- case fetch_token_str(conn) do
- {:ok, token} ->
- with {:ok, user, token_record} <- fetch_user_and_token(token) do
- conn
- |> assign(:token, token_record)
- |> assign(:user, user)
- else
- _ ->
- # token found, but maybe only with app
- with {:ok, app, token_record} <- fetch_app_and_token(token) do
- conn
- |> assign(:token, token_record)
- |> assign(:app, app)
- else
- _ -> conn
- end
- end
-
- _ ->
+ with {:ok, token_str} <- fetch_token_str(conn) do
+ with {:ok, user, user_token} <- fetch_user_and_token(token_str),
+ false <- Token.is_expired?(user_token) do
conn
+ |> assign(:token, user_token)
+ |> assign(:user, user)
+ else
+ _ ->
+ with {:ok, app, app_token} <- fetch_app_and_token(token_str),
+ false <- Token.is_expired?(app_token) do
+ conn
+ |> assign(:token, app_token)
+ |> assign(:app, app)
+ else
+ _ -> conn
+ end
+ end
+ else
+ _ -> conn
end
end
@@ -70,7 +53,6 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
preload: [user: user]
)
- # credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
with %Token{user: user} = token_record <- Repo.one(query) do
{:ok, user, token_record}
end
@@ -86,29 +68,23 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
end
end
- # Gets token from session by :oauth_token key
+ # Gets token string from conn (in params / headers / session)
#
- @spec fetch_token_from_session(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()}
- defp fetch_token_from_session(conn) do
- case get_session(conn, :oauth_token) do
- nil -> :no_token_found
- token -> {:ok, token}
- end
+ @spec fetch_token_str(Plug.Conn.t() | list(String.t())) :: :no_token_found | {:ok, String.t()}
+ defp fetch_token_str(%Plug.Conn{params: %{"access_token" => access_token}} = _conn) do
+ {:ok, access_token}
end
- # Gets token from headers
- #
- @spec fetch_token_str(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()}
defp fetch_token_str(%Plug.Conn{} = conn) do
headers = get_req_header(conn, "authorization")
- with :no_token_found <- fetch_token_str(headers),
- do: fetch_token_from_session(conn)
+ with {:ok, token} <- fetch_token_str(headers) do
+ {:ok, token}
+ else
+ _ -> fetch_token_from_session(conn)
+ end
end
- @spec fetch_token_str(Keyword.t()) :: :no_token_found | {:ok, String.t()}
- defp fetch_token_str([]), do: :no_token_found
-
defp fetch_token_str([token | tail]) do
trimmed_token = String.trim(token)
@@ -117,4 +93,14 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
_ -> fetch_token_str(tail)
end
end
+
+ defp fetch_token_str([]), do: :no_token_found
+
+ @spec fetch_token_from_session(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()}
+ defp fetch_token_from_session(conn) do
+ case get_session(conn, :oauth_token) do
+ nil -> :no_token_found
+ token -> {:ok, token}
+ end
+ end
end
diff --git a/lib/pleroma/web/plugs/session_authentication_plug.ex b/lib/pleroma/web/plugs/session_authentication_plug.ex
deleted file mode 100644
index 6e176d553..000000000
--- a/lib/pleroma/web/plugs/session_authentication_plug.ex
+++ /dev/null
@@ -1,21 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Plugs.SessionAuthenticationPlug do
- import Plug.Conn
-
- def init(options) do
- options
- end
-
- def call(conn, _) do
- with saved_user_id <- get_session(conn, :user_id),
- %{auth_user: %{id: ^saved_user_id}} <- conn.assigns do
- conn
- |> assign(:user, conn.assigns.auth_user)
- else
- _ -> conn
- end
- end
-end
diff --git a/lib/pleroma/web/plugs/set_user_session_id_plug.ex b/lib/pleroma/web/plugs/set_user_session_id_plug.ex
index e520159e4..d2338c03f 100644
--- a/lib/pleroma/web/plugs/set_user_session_id_plug.ex
+++ b/lib/pleroma/web/plugs/set_user_session_id_plug.ex
@@ -4,15 +4,15 @@
defmodule Pleroma.Web.Plugs.SetUserSessionIdPlug do
import Plug.Conn
- alias Pleroma.User
+
+ alias Pleroma.Web.OAuth.Token
def init(opts) do
opts
end
- def call(%{assigns: %{user: %User{id: id}}} = conn, _) do
- conn
- |> put_session(:user_id, id)
+ def call(%{assigns: %{token: %Token{} = oauth_token}} = conn, _) do
+ put_session(conn, :oauth_token, oauth_token.token)
end
def call(conn, _), do: conn
diff --git a/lib/pleroma/web/plugs/user_enabled_plug.ex b/lib/pleroma/web/plugs/user_enabled_plug.ex
index fa28ee48b..291d1f568 100644
--- a/lib/pleroma/web/plugs/user_enabled_plug.ex
+++ b/lib/pleroma/web/plugs/user_enabled_plug.ex
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.UserEnabledPlug do
- import Plug.Conn
+ alias Pleroma.Helpers.AuthHelper
alias Pleroma.User
def init(options) do
@@ -12,8 +12,11 @@ defmodule Pleroma.Web.Plugs.UserEnabledPlug do
def call(%{assigns: %{user: %User{} = user}} = conn, _) do
case User.account_status(user) do
- :active -> conn
- _ -> assign(conn, :user, nil)
+ :active ->
+ conn
+
+ _ ->
+ AuthHelper.drop_auth_info(conn)
end
end
diff --git a/lib/pleroma/web/plugs/user_fetcher_plug.ex b/lib/pleroma/web/plugs/user_fetcher_plug.ex
index 4039600da..89e16b49f 100644
--- a/lib/pleroma/web/plugs/user_fetcher_plug.ex
+++ b/lib/pleroma/web/plugs/user_fetcher_plug.ex
@@ -3,6 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.UserFetcherPlug do
+ @moduledoc """
+ Assigns `:auth_user` basing on `:auth_credentials`.
+
+ NOTE: no checks are performed at this step, auth_credentials/username could be easily faked.
+ """
+
alias Pleroma.User
import Plug.Conn
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 75a885377..3a3e63db6 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -34,6 +34,7 @@ defmodule Pleroma.Web.Router do
plug(:fetch_session)
plug(Pleroma.Web.Plugs.OAuthPlug)
plug(Pleroma.Web.Plugs.UserEnabledPlug)
+ plug(Pleroma.Web.Plugs.EnsureUserKeyPlug)
end
pipeline :expect_authentication do
@@ -48,8 +49,6 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.OAuthPlug)
plug(Pleroma.Web.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Web.Plugs.UserFetcherPlug)
- plug(Pleroma.Web.Plugs.SessionAuthenticationPlug)
- plug(Pleroma.Web.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Web.Plugs.AuthenticationPlug)
end
@@ -323,12 +322,12 @@ defmodule Pleroma.Web.Router do
scope "/oauth", Pleroma.Web.OAuth do
scope [] do
pipe_through(:oauth)
+
get("/authorize", OAuthController, :authorize)
+ post("/authorize", OAuthController, :create_authorization)
end
- post("/authorize", OAuthController, :create_authorization)
post("/token", OAuthController, :token_exchange)
- post("/revoke", OAuthController, :token_revoke)
get("/registration_details", OAuthController, :registration_details)
post("/mfa/challenge", MFAController, :challenge)
@@ -336,6 +335,12 @@ defmodule Pleroma.Web.Router do
get("/mfa", MFAController, :show)
scope [] do
+ pipe_through(:fetch_session)
+
+ post("/revoke", OAuthController, :token_revoke)
+ end
+
+ scope [] do
pipe_through(:browser)
get("/prepare_request", OAuthController, :prepare_request)
diff --git a/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs b/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs
index 33394722a..23498badf 100644
--- a/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs
+++ b/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs
@@ -49,6 +49,7 @@ defmodule Pleroma.Web.Plugs.AdminSecretAuthenticationPlugTest do
|> AdminSecretAuthenticationPlug.call(%{})
assert conn.assigns[:user].is_admin
+ assert conn.assigns[:token] == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
end
@@ -69,6 +70,7 @@ defmodule Pleroma.Web.Plugs.AdminSecretAuthenticationPlugTest do
|> AdminSecretAuthenticationPlug.call(%{})
assert conn.assigns[:user].is_admin
+ assert conn.assigns[:token] == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
end
end
diff --git a/test/pleroma/web/plugs/authentication_plug_test.exs b/test/pleroma/web/plugs/authentication_plug_test.exs
index af39352e2..3dedd38b2 100644
--- a/test/pleroma/web/plugs/authentication_plug_test.exs
+++ b/test/pleroma/web/plugs/authentication_plug_test.exs
@@ -48,6 +48,7 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
|> AuthenticationPlug.call(%{})
assert conn.assigns.user == conn.assigns.auth_user
+ assert conn.assigns.token == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
end
@@ -62,6 +63,7 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
|> AuthenticationPlug.call(%{})
assert conn.assigns.user.id == conn.assigns.auth_user.id
+ assert conn.assigns.token == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
user = User.get_by_id(user.id)
@@ -83,6 +85,7 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
|> AuthenticationPlug.call(%{})
assert conn.assigns.user.id == conn.assigns.auth_user.id
+ assert conn.assigns.token == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
user = User.get_by_id(user.id)
diff --git a/test/pleroma/web/plugs/legacy_authentication_plug_test.exs b/test/pleroma/web/plugs/legacy_authentication_plug_test.exs
deleted file mode 100644
index 2016a31a8..000000000
--- a/test/pleroma/web/plugs/legacy_authentication_plug_test.exs
+++ /dev/null
@@ -1,82 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Plugs.LegacyAuthenticationPlugTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.User
- alias Pleroma.Web.Plugs.LegacyAuthenticationPlug
- alias Pleroma.Web.Plugs.OAuthScopesPlug
- alias Pleroma.Web.Plugs.PlugHelper
-
- setup do
- user =
- insert(:user,
- password: "password",
- password_hash:
- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
- )
-
- %{user: user}
- end
-
- test "it does nothing if a user is assigned", %{conn: conn, user: user} do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "password"})
- |> assign(:auth_user, user)
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- @tag :skip_on_mac
- test "if `auth_user` is present and password is correct, " <>
- "it authenticates the user, resets the password, marks OAuthScopesPlug as skipped",
- %{
- conn: conn,
- user: user
- } do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "password"})
- |> assign(:auth_user, user)
-
- conn = LegacyAuthenticationPlug.call(conn, %{})
-
- assert conn.assigns.user.id == user.id
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
- end
-
- @tag :skip_on_mac
- test "it does nothing if the password is wrong", %{
- conn: conn,
- user: user
- } do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "wrong_password"})
- |> assign(:auth_user, user)
-
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert conn == ret_conn
- end
-
- test "with no credentials or user it does nothing", %{conn: conn} do
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-end
diff --git a/test/pleroma/web/plugs/o_auth_plug_test.exs b/test/pleroma/web/plugs/o_auth_plug_test.exs
index b9d722f76..ad2aa5d1b 100644
--- a/test/pleroma/web/plugs/o_auth_plug_test.exs
+++ b/test/pleroma/web/plugs/o_auth_plug_test.exs
@@ -5,43 +5,48 @@
defmodule Pleroma.Web.Plugs.OAuthPlugTest do
use Pleroma.Web.ConnCase, async: true
+ alias Pleroma.Web.OAuth.Token
+ alias Pleroma.Web.OAuth.Token.Strategy.Revoke
alias Pleroma.Web.Plugs.OAuthPlug
- import Pleroma.Factory
+ alias Plug.Session
- @session_opts [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
+ import Pleroma.Factory
setup %{conn: conn} do
user = insert(:user)
- {:ok, %{token: token}} = Pleroma.Web.OAuth.Token.create(insert(:oauth_app), user)
- %{user: user, token: token, conn: conn}
+ {:ok, oauth_token} = Token.create(insert(:oauth_app), user)
+ %{user: user, token: oauth_token, conn: conn}
+ end
+
+ test "it does nothing if a user is assigned", %{conn: conn} do
+ conn = assign(conn, :user, %Pleroma.User{})
+ ret_conn = OAuthPlug.call(conn, %{})
+
+ assert ret_conn == conn
end
- test "with valid token(uppercase), it assigns the user", %{conn: conn} = opts do
+ test "with valid token (uppercase) in auth header, it assigns the user", %{conn: conn} = opts do
conn =
conn
- |> put_req_header("authorization", "BEARER #{opts[:token]}")
+ |> put_req_header("authorization", "BEARER #{opts[:token].token}")
|> OAuthPlug.call(%{})
assert conn.assigns[:user] == opts[:user]
end
- test "with valid token(downcase), it assigns the user", %{conn: conn} = opts do
+ test "with valid token (downcase) in auth header, it assigns the user", %{conn: conn} = opts do
conn =
conn
- |> put_req_header("authorization", "bearer #{opts[:token]}")
+ |> put_req_header("authorization", "bearer #{opts[:token].token}")
|> OAuthPlug.call(%{})
assert conn.assigns[:user] == opts[:user]
end
- test "with valid token(downcase) in url parameters, it assigns the user", opts do
+ test "with valid token (downcase) in url parameters, it assigns the user", opts do
conn =
:get
- |> build_conn("/?access_token=#{opts[:token]}")
+ |> build_conn("/?access_token=#{opts[:token].token}")
|> put_req_header("content-type", "application/json")
|> fetch_query_params()
|> OAuthPlug.call(%{})
@@ -49,16 +54,16 @@ defmodule Pleroma.Web.Plugs.OAuthPlugTest do
assert conn.assigns[:user] == opts[:user]
end
- test "with valid token(downcase) in body parameters, it assigns the user", opts do
+ test "with valid token (downcase) in body parameters, it assigns the user", opts do
conn =
:post
- |> build_conn("/api/v1/statuses", access_token: opts[:token], status: "test")
+ |> build_conn("/api/v1/statuses", access_token: opts[:token].token, status: "test")
|> OAuthPlug.call(%{})
assert conn.assigns[:user] == opts[:user]
end
- test "with invalid token, it not assigns the user", %{conn: conn} do
+ test "with invalid token, it does not assign the user", %{conn: conn} do
conn =
conn
|> put_req_header("authorization", "bearer TTTTT")
@@ -67,14 +72,56 @@ defmodule Pleroma.Web.Plugs.OAuthPlugTest do
refute conn.assigns[:user]
end
- test "when token is missed but token in session, it assigns the user", %{conn: conn} = opts do
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(@session_opts))
- |> fetch_session()
- |> put_session(:oauth_token, opts[:token])
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
+ describe "with :oauth_token in session, " do
+ setup %{token: oauth_token, conn: conn} do
+ session_opts = [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
+ conn =
+ conn
+ |> Session.call(Session.init(session_opts))
+ |> fetch_session()
+ |> put_session(:oauth_token, oauth_token.token)
+
+ %{conn: conn}
+ end
+
+ test "if session-stored token matches a valid OAuth token, assigns :user and :token", %{
+ conn: conn,
+ user: user,
+ token: oauth_token
+ } do
+ conn = OAuthPlug.call(conn, %{})
+
+ assert conn.assigns.user && conn.assigns.user.id == user.id
+ assert conn.assigns.token && conn.assigns.token.id == oauth_token.id
+ end
+
+ test "if session-stored token matches an expired OAuth token, does nothing", %{
+ conn: conn,
+ token: oauth_token
+ } do
+ expired_valid_until = NaiveDateTime.add(NaiveDateTime.utc_now(), -3600 * 24, :second)
+
+ oauth_token
+ |> Ecto.Changeset.change(valid_until: expired_valid_until)
+ |> Pleroma.Repo.update()
+
+ ret_conn = OAuthPlug.call(conn, %{})
+ assert ret_conn == conn
+ end
+
+ test "if session-stored token matches a revoked OAuth token, does nothing", %{
+ conn: conn,
+ token: oauth_token
+ } do
+ Revoke.revoke(oauth_token)
+
+ ret_conn = OAuthPlug.call(conn, %{})
+ assert ret_conn == conn
+ end
end
end
diff --git a/test/pleroma/web/plugs/session_authentication_plug_test.exs b/test/pleroma/web/plugs/session_authentication_plug_test.exs
deleted file mode 100644
index 2b4d5bc0c..000000000
--- a/test/pleroma/web/plugs/session_authentication_plug_test.exs
+++ /dev/null
@@ -1,63 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Plugs.SessionAuthenticationPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.User
- alias Pleroma.Web.Plugs.SessionAuthenticationPlug
-
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session
- |> assign(:auth_user, %User{id: 1})
-
- %{conn: conn}
- end
-
- test "it does nothing if a user is assigned", %{conn: conn} do
- conn =
- conn
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> SessionAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- test "if the auth_user has the same id as the user_id in the session, it assigns the user", %{
- conn: conn
- } do
- conn =
- conn
- |> put_session(:user_id, conn.assigns.auth_user.id)
- |> SessionAuthenticationPlug.call(%{})
-
- assert conn.assigns.user == conn.assigns.auth_user
- end
-
- test "if the auth_user has a different id as the user_id in the session, it does nothing", %{
- conn: conn
- } do
- conn =
- conn
- |> put_session(:user_id, -1)
-
- ret_conn =
- conn
- |> SessionAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-end
diff --git a/test/pleroma/web/plugs/set_user_session_id_plug_test.exs b/test/pleroma/web/plugs/set_user_session_id_plug_test.exs
index a89b5628f..a50e80107 100644
--- a/test/pleroma/web/plugs/set_user_session_id_plug_test.exs
+++ b/test/pleroma/web/plugs/set_user_session_id_plug_test.exs
@@ -5,7 +5,6 @@
defmodule Pleroma.Web.Plugs.SetUserSessionIdPlugTest do
use Pleroma.Web.ConnCase, async: true
- alias Pleroma.User
alias Pleroma.Web.Plugs.SetUserSessionIdPlug
setup %{conn: conn} do
@@ -18,28 +17,26 @@ defmodule Pleroma.Web.Plugs.SetUserSessionIdPlugTest do
conn =
conn
|> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session
+ |> fetch_session()
%{conn: conn}
end
test "doesn't do anything if the user isn't set", %{conn: conn} do
- ret_conn =
- conn
- |> SetUserSessionIdPlug.call(%{})
+ ret_conn = SetUserSessionIdPlug.call(conn, %{})
assert ret_conn == conn
end
- test "sets the user_id in the session to the user id of the user assign", %{conn: conn} do
- Code.ensure_compiled(Pleroma.User)
+ test "sets :oauth_token in session to :token assign", %{conn: conn} do
+ %{user: user, token: oauth_token} = oauth_access(["read"])
- conn =
+ ret_conn =
conn
- |> assign(:user, %User{id: 1})
+ |> assign(:user, user)
+ |> assign(:token, oauth_token)
|> SetUserSessionIdPlug.call(%{})
- id = get_session(conn, :user_id)
- assert id == 1
+ assert get_session(ret_conn, :oauth_token) == oauth_token.token
end
end