digest algorithm is taken from header
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Thu, 26 Nov 2020 08:12:44 +0000 (11:12 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 27 Nov 2020 05:10:52 +0000 (08:10 +0300)
lib/pleroma/web/plugs/digest_plug.ex
test/pleroma/web/plugs/digest_plug_test.exs [new file with mode: 0644]

index b521b30732460910a7c8f24dfe29291293b451fb..fb2723b97a346b3444d0edc4f8ff205f61ba3296 100644 (file)
@@ -7,8 +7,22 @@ defmodule Pleroma.Web.Plugs.DigestPlug do
   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
diff --git a/test/pleroma/web/plugs/digest_plug_test.exs b/test/pleroma/web/plugs/digest_plug_test.exs
new file mode 100644 (file)
index 0000000..629c28c
--- /dev/null
@@ -0,0 +1,48 @@
+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