Merge branch 'feature/signed-object-fetches' into 'develop'
signed object fetches See merge request pleroma/pleroma!1446
This commit is contained in:
commit
f9a0014681
|
@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Addressable lists
|
||||
- Twitter API: added rate limit for `/api/account/password_reset` endpoint.
|
||||
- ActivityPub: Add an internal service actor for fetching ActivityPub objects.
|
||||
- ActivityPub: Optional signing of ActivityPub object fetches.
|
||||
|
||||
### Changed
|
||||
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
|
||||
|
|
|
@ -305,7 +305,8 @@
|
|||
accept_blocks: true,
|
||||
unfollow_blocked: true,
|
||||
outgoing_blocks: true,
|
||||
follow_handshake_timeout: 500
|
||||
follow_handshake_timeout: 500,
|
||||
sign_object_fetches: true
|
||||
|
||||
config :pleroma, :user, deny_follow_blocked: true
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
skip_thread_containment: false,
|
||||
federating: false
|
||||
|
||||
config :pleroma, :activitypub, sign_object_fetches: false
|
||||
|
||||
# Configure your database
|
||||
config :pleroma, Pleroma.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
|
|
|
@ -332,6 +332,7 @@ This will make Pleroma listen on `127.0.0.1` port `8080` and generate urls start
|
|||
* ``unfollow_blocked``: Whether blocks result in people getting unfollowed
|
||||
* ``outgoing_blocks``: Whether to federate blocks to other instances
|
||||
* ``deny_follow_blocked``: Whether to disallow following an account that has blocked the user in question
|
||||
* ``sign_object_fetches``: Sign object fetches with HTTP signatures
|
||||
|
||||
## :http_security
|
||||
* ``enabled``: Whether the managed content security policy is enabled
|
||||
|
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Object.Fetcher do
|
|||
alias Pleroma.HTTP
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Containment
|
||||
alias Pleroma.Signature
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.OStatus
|
||||
|
||||
|
@ -82,15 +84,52 @@ def fetch_object_from_id!(id, options \\ []) do
|
|||
end
|
||||
end
|
||||
|
||||
defp make_signature(id, date) do
|
||||
uri = URI.parse(id)
|
||||
|
||||
signature =
|
||||
InternalFetchActor.get_actor()
|
||||
|> Signature.sign(%{
|
||||
"(request-target)": "get #{uri.path}",
|
||||
host: uri.host,
|
||||
date: date
|
||||
})
|
||||
|
||||
[{:Signature, signature}]
|
||||
end
|
||||
|
||||
defp sign_fetch(headers, id, date) do
|
||||
if Pleroma.Config.get([:activitypub, :sign_object_fetches]) do
|
||||
headers ++ make_signature(id, date)
|
||||
else
|
||||
headers
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_date_fetch(headers, date) do
|
||||
if Pleroma.Config.get([:activitypub, :sign_object_fetches]) do
|
||||
headers ++ [{:Date, date}]
|
||||
else
|
||||
headers
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_and_contain_remote_object_from_id(id) do
|
||||
Logger.info("Fetching object #{id} via AP")
|
||||
|
||||
date =
|
||||
NaiveDateTime.utc_now()
|
||||
|> Timex.format!("{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT")
|
||||
|
||||
headers =
|
||||
[{:Accept, "application/activity+json"}]
|
||||
|> maybe_date_fetch(date)
|
||||
|> sign_fetch(id, date)
|
||||
|
||||
Logger.debug("Fetch headers: #{inspect(headers)}")
|
||||
|
||||
with true <- String.starts_with?(id, "http"),
|
||||
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||
HTTP.get(
|
||||
id,
|
||||
[{:Accept, "application/activity+json"}]
|
||||
),
|
||||
{:ok, %{body: body, status: code}} when code in 200..299 <- HTTP.get(id, headers),
|
||||
{:ok, data} <- Jason.decode(body),
|
||||
:ok <- Containment.contain_origin_from_id(id, data) do
|
||||
{:ok, data}
|
||||
|
|
|
@ -150,4 +150,34 @@ test "it can refetch pruned objects" do
|
|||
assert object.id != object_two.id
|
||||
end
|
||||
end
|
||||
|
||||
describe "signed fetches" do
|
||||
test_with_mock "it signs fetches when configured to do so",
|
||||
Pleroma.Signature,
|
||||
[:passthrough],
|
||||
[] do
|
||||
option = Pleroma.Config.get([:activitypub, :sign_object_fetches])
|
||||
Pleroma.Config.put([:activitypub, :sign_object_fetches], true)
|
||||
|
||||
Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
|
||||
|
||||
assert called(Pleroma.Signature.sign(:_, :_))
|
||||
|
||||
Pleroma.Config.put([:activitypub, :sign_object_fetches], option)
|
||||
end
|
||||
|
||||
test_with_mock "it doesn't sign fetches when not configured to do so",
|
||||
Pleroma.Signature,
|
||||
[:passthrough],
|
||||
[] do
|
||||
option = Pleroma.Config.get([:activitypub, :sign_object_fetches])
|
||||
Pleroma.Config.put([:activitypub, :sign_object_fetches], false)
|
||||
|
||||
Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
|
||||
|
||||
refute called(Pleroma.Signature.sign(:_, :_))
|
||||
|
||||
Pleroma.Config.put([:activitypub, :sign_object_fetches], option)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue