require Logger
def read_body(conn, opts) do
+ digest_algorithm =
+ with [digest_header] <- Conn.get_req_header(conn, "digest") do
+ digest_header
+ |> String.split("=", parts: 2)
+ |> List.first()
+ else
+ _ -> "SHA-256"
+ end
+
+ unless String.downcase(digest_algorithm) == "sha-256" do
+ raise ArgumentError,
+ message: "invalid value for digest algorithm, got: #{digest_algorithm}"
+ end
+
{:ok, body, conn} = Conn.read_body(conn, opts)
- digest = "SHA-256=" <> (:crypto.hash(:sha256, body) |> Base.encode64())
- {:ok, body, Conn.assign(conn, :digest, digest)}
+ encoded_digest = :crypto.hash(:sha256, body) |> Base.encode64()
+ {:ok, body, Conn.assign(conn, :digest, "#{digest_algorithm}=#{encoded_digest}")}
end
end
--- /dev/null
+defmodule Pleroma.Web.Plugs.DigestPlugTest do
+ use ExUnit.Case, async: true
+ use Plug.Test
+
+ test "digest algorithm is taken from digest header" do
+ body = "{\"hello\": \"world\"}"
+ digest = "X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE="
+
+ {:ok, ^body, conn} =
+ :get
+ |> conn("/", body)
+ |> put_req_header("content-type", "application/json")
+ |> put_req_header("digest", "sha-256=" <> digest)
+ |> Pleroma.Web.Plugs.DigestPlug.read_body([])
+
+ assert conn.assigns[:digest] == "sha-256=" <> digest
+
+ {:ok, ^body, conn} =
+ :get
+ |> conn("/", body)
+ |> put_req_header("content-type", "application/json")
+ |> put_req_header("digest", "SHA-256=" <> digest)
+ |> Pleroma.Web.Plugs.DigestPlug.read_body([])
+
+ assert conn.assigns[:digest] == "SHA-256=" <> digest
+ end
+
+ test "error if digest algorithm is invalid" do
+ body = "{\"hello\": \"world\"}"
+ digest = "X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE="
+
+ assert_raise ArgumentError, "invalid value for digest algorithm, got: MD5", fn ->
+ :get
+ |> conn("/", body)
+ |> put_req_header("content-type", "application/json")
+ |> put_req_header("digest", "MD5=" <> digest)
+ |> Pleroma.Web.Plugs.DigestPlug.read_body([])
+ end
+
+ assert_raise ArgumentError, "invalid value for digest algorithm, got: md5", fn ->
+ :get
+ |> conn("/", body)
+ |> put_req_header("content-type", "application/json")
+ |> put_req_header("digest", "md5=" <> digest)
+ |> Pleroma.Web.Plugs.DigestPlug.read_body([])
+ end
+ end
+end