logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma
commit: bf89e0bf38d9709f6dd331f5d9b326575994423d
parent: 06151776c0c2c529a1bd3b4866162794c141e95f
Author: lain <lain@soykaf.club>
Date:   Tue, 19 Nov 2019 13:16:49 +0000

Merge branch 'feature/admin-api/support-token-header' into 'develop'

Admin API: Support authentication via `x-admin-token` HTTP header

Closes #1430

See merge request pleroma/pleroma!1993

Diffstat:

MCHANGELOG.md1+
Mdocs/configuration/cheatsheet.md12+++++++++---
Mlib/pleroma/plugs/admin_secret_authentication_plug.ex22++++++++++++++++++----
Mtest/plugs/admin_secret_authentication_plug_test.exs42++++++++++++++++++++++++++++++------------
4 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Admin API: Return `total` when querying for reports - Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`) - Admin API: Return link alongside with token on password reset +- Admin API: Support authentication via `x-admin-token` HTTP header - Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`) - Mastodon API: `pleroma.thread_muted` to the Status entity - Mastodon API: Mark the direct conversation as read for the author when they send a new direct message diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md @@ -656,7 +656,7 @@ Feel free to adjust the priv_dir and port number. Then you will have to create t ### :admin_token -Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter. Example: +Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter or `x-admin-token` HTTP header. Example: ```elixir config :pleroma, :admin_token, "somerandomtoken" @@ -664,8 +664,14 @@ config :pleroma, :admin_token, "somerandomtoken" You can then do -```sh -curl "http://localhost:4000/api/pleroma/admin/invite_token?admin_token=somerandomtoken" +```shell +curl "http://localhost:4000/api/pleroma/admin/users/invites?admin_token=somerandomtoken" +``` + +or + +```shell +curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites" ``` ### :auth diff --git a/lib/pleroma/plugs/admin_secret_authentication_plug.ex b/lib/pleroma/plugs/admin_secret_authentication_plug.ex @@ -16,14 +16,28 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do def call(%{assigns: %{user: %User{}}} = conn, _), do: conn - def call(%{params: %{"admin_token" => admin_token}} = conn, _) do - if secret_token() && admin_token == secret_token() do + def call(conn, _) do + if secret_token() do + authenticate(conn) + else conn - |> assign(:user, %User{is_admin: true}) + end + end + + def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do + if admin_token == secret_token() do + assign(conn, :user, %User{is_admin: true}) else conn end end - def call(conn, _), do: conn + def authenticate(conn) do + token = secret_token() + + case get_req_header(conn, "x-admin-token") do + [^token] -> assign(conn, :user, %User{is_admin: true}) + _ -> conn + end + end end diff --git a/test/plugs/admin_secret_authentication_plug_test.exs b/test/plugs/admin_secret_authentication_plug_test.exs @@ -22,21 +22,39 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do assert conn == ret_conn end - test "with secret set and given in the 'admin_token' parameter, it assigns an admin user", %{ - conn: conn - } do - Pleroma.Config.put(:admin_token, "password123") + describe "when secret set it assigns an admin user" do + test "with `admin_token` query parameter", %{conn: conn} do + Pleroma.Config.put(:admin_token, "password123") - conn = - %{conn | params: %{"admin_token" => "wrong_password"}} - |> AdminSecretAuthenticationPlug.call(%{}) + conn = + %{conn | params: %{"admin_token" => "wrong_password"}} + |> AdminSecretAuthenticationPlug.call(%{}) - refute conn.assigns[:user] + refute conn.assigns[:user] - conn = - %{conn | params: %{"admin_token" => "password123"}} - |> AdminSecretAuthenticationPlug.call(%{}) + conn = + %{conn | params: %{"admin_token" => "password123"}} + |> AdminSecretAuthenticationPlug.call(%{}) + + assert conn.assigns[:user].is_admin + end + + test "with `x-admin-token` HTTP header", %{conn: conn} do + Pleroma.Config.put(:admin_token, "☕️") + + conn = + conn + |> put_req_header("x-admin-token", "🥛") + |> AdminSecretAuthenticationPlug.call(%{}) + + refute conn.assigns[:user] + + conn = + conn + |> put_req_header("x-admin-token", "☕️") + |> AdminSecretAuthenticationPlug.call(%{}) - assert conn.assigns[:user].is_admin + assert conn.assigns[:user].is_admin + end end end