1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
6 use Pleroma.Web.ConnCase, async: false
8 alias Pleroma.Web.Plugs.HTTPSignaturePlug
9 alias Pleroma.Instances.Instance
13 import Phoenix.Controller, only: [put_format: 2]
19 signature_for_conn: fn _ ->
20 %{"keyId" => "http://mastodon.example.org/users/admin#main-key"}
22 validate_conn: fn conn ->
23 Map.get(conn.assigns, :valid_signature, true)
30 defp submit_to_plug(host), do: submit_to_plug(host, :get, "/doesntmattter")
32 defp submit_to_plug(host, method, path) do
33 params = %{"actor" => "http://#{host}/users/admin"}
35 build_conn(method, path, params)
38 "keyId=\"http://#{host}/users/admin#main-key"
40 |> put_format("activity+json")
41 |> HTTPSignaturePlug.call(%{})
44 test "it call HTTPSignatures to check validity if the actor signed it" do
45 params = %{"actor" => "http://mastodon.example.org/users/admin"}
46 conn = build_conn(:get, "/doesntmattter", params)
52 "keyId=\"http://mastodon.example.org/users/admin#main-key"
54 |> put_format("activity+json")
55 |> HTTPSignaturePlug.call(%{})
57 assert conn.assigns.valid_signature == true
58 assert conn.assigns.signature_actor_id == params["actor"]
59 assert conn.halted == false
60 assert called(HTTPSignatures.validate_conn(:_))
63 test "it sets request signatures property on the instance" do
64 host = "mastodon.example.org"
65 conn = submit_to_plug(host)
66 assert conn.assigns.valid_signature == true
67 instance = Repo.get_by(Instance, %{host: host})
68 assert instance.has_request_signatures
71 test "it does not set request signatures property on the instance when using inbox" do
72 host = "mastodon.example.org"
73 conn = submit_to_plug(host, :post, "/inbox")
74 assert conn.assigns.valid_signature == true
76 # we don't even create the instance entry if its just POST /inbox
77 refute Repo.get_by(Instance, %{host: host})
80 test "it does not set request signatures property on the instance when its cached" do
81 host = "mastodon.example.org"
82 Cachex.put(:request_signatures_cache, host, true)
83 conn = submit_to_plug(host)
84 assert conn.assigns.valid_signature == true
86 # we don't even create the instance entry if it was already done
87 refute Repo.get_by(Instance, %{host: host})
90 describe "requires a signature when `authorized_fetch_mode` is enabled" do
92 clear_config([:activitypub, :authorized_fetch_mode], true)
94 params = %{"actor" => "http://mastodon.example.org/users/admin"}
95 conn = build_conn(:get, "/doesntmattter", params) |> put_format("activity+json")
100 test "and signature is present and incorrect", %{conn: conn} do
103 |> assign(:valid_signature, false)
106 "keyId=\"http://mastodon.example.org/users/admin#main-key"
108 |> HTTPSignaturePlug.call(%{})
110 assert conn.assigns.valid_signature == false
111 assert called(HTTPSignatures.validate_conn(:_))
114 test "and signature is correct", %{conn: conn} do
119 "keyId=\"http://mastodon.example.org/users/admin#main-key"
121 |> HTTPSignaturePlug.call(%{})
123 assert conn.assigns.valid_signature == true
124 assert called(HTTPSignatures.validate_conn(:_))
127 test "and halts the connection when `signature` header is not present", %{conn: conn} do
128 conn = HTTPSignaturePlug.call(conn, %{})
129 assert conn.assigns[:valid_signature] == nil
133 test "aliases redirected /object endpoints", _ do
135 act = insert(:note_activity, note: obj)
136 params = %{"actor" => "someparam"}
137 path = URI.parse(obj.data["id"]).path
138 conn = build_conn(:get, path, params)
140 assert ["/notice/#{act.id}", "/notice/#{act.id}?actor=someparam"] ==
141 HTTPSignaturePlug.route_aliases(conn)