From 0a14d155d6a55366449bc8dea638e24200bb3dd0 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 2 Apr 2018 13:13:14 +0200 Subject: [PATCH] Fail faster. --- lib/pleroma/plugs/http_signature.ex | 29 +++++++++------- test/plugs/http_signature_plug_test.exs | 44 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 test/plugs/http_signature_plug_test.exs diff --git a/lib/pleroma/plugs/http_signature.ex b/lib/pleroma/plugs/http_signature.ex index af160f3ee..8b9ccdd2d 100644 --- a/lib/pleroma/plugs/http_signature.ex +++ b/lib/pleroma/plugs/http_signature.ex @@ -14,19 +14,26 @@ def call(%{assigns: %{valid_signature: true}} = conn, opts) do def call(conn, opts) do user = conn.params["actor"] Logger.debug("Checking sig for #{user}") + [signature | _] = get_req_header(conn, "signature") - if get_req_header(conn, "signature") do - conn = + cond do + signature && String.contains?(signature, user) -> + conn = + conn + |> put_req_header( + "(request-target)", + String.downcase("#{conn.method}") <> " #{conn.request_path}" + ) + + assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn)) + + signature -> + Logger.debug("Signature not from actor") + assign(conn, :valid_signature, false) + + true -> + Logger.debug("No signature header!") conn - |> put_req_header( - "(request-target)", - String.downcase("#{conn.method}") <> " #{conn.request_path}" - ) - - assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn)) - else - Logger.debug("No signature header!") - conn end end end diff --git a/test/plugs/http_signature_plug_test.exs b/test/plugs/http_signature_plug_test.exs new file mode 100644 index 000000000..a15c5b470 --- /dev/null +++ b/test/plugs/http_signature_plug_test.exs @@ -0,0 +1,44 @@ +defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do + use Pleroma.Web.ConnCase + alias Pleroma.Web.HTTPSignatures + alias Pleroma.Web.Plugs.HTTPSignaturePlug + + import Plug.Conn + import Mock + + test "it call HTTPSignatures to check validity if the actor sighed it" do + params = %{"actor" => "http://mastodon.example.org/users/admin"} + conn = build_conn(:get, "/doesntmattter", params) + + with_mock HTTPSignatures, validate_conn: fn _ -> true end do + conn = + conn + |> put_req_header( + "signature", + "keyId=\"http://mastodon.example.org/users/admin#main-key" + ) + |> HTTPSignaturePlug.call(%{}) + + assert conn.assigns.valid_signature == true + assert called(HTTPSignatures.validate_conn(:_)) + end + end + + test "bails out early if the signature isn't by the activity actor" do + params = %{"actor" => "https://mst3k.interlinked.me/users/luciferMysticus"} + conn = build_conn(:get, "/doesntmattter", params) + + with_mock HTTPSignatures, validate_conn: fn _ -> false end do + conn = + conn + |> put_req_header( + "signature", + "keyId=\"http://mastodon.example.org/users/admin#main-key" + ) + |> HTTPSignaturePlug.call(%{}) + + assert conn.assigns.valid_signature == false + refute called(HTTPSignatures.validate_conn(:_)) + end + end +end