1
0
Fork 1
mirror of https://akkoma.dev/AkkomaGang/akkoma.git synced 2024-11-17 18:49:15 +00:00
akkoma/test/support/http_request_mock.ex

1783 lines
48 KiB
Elixir
Raw Normal View History

2018-12-23 20:11:29 +00:00
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
2018-12-23 20:11:29 +00:00
# SPDX-License-Identifier: AGPL-3.0-only
2018-12-02 15:17:26 +00:00
defmodule HttpRequestMock do
2018-12-02 19:05:28 +00:00
require Logger
def activitypub_object_headers,
do: [
{"content-type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""}
]
# The Accept headers we genrate to be exact; AP spec only requires the first somewhere
@activitypub_accept_headers [
{"accept", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""},
{"accept", "application/activity+json"}
]
2018-12-02 15:17:26 +00:00
def request(
%Tesla.Env{
url: url,
method: method,
headers: headers,
query: query,
body: body
} = _env
) do
with {:ok, res} <- apply(__MODULE__, method, [url, query, body, headers]) do
res
else
error ->
with {:error, message} <- error do
Logger.warning(to_string(message))
end
{_, _r} = error
2018-12-02 15:17:26 +00:00
end
end
# GET Requests
#
def get(url, query \\ [], body \\ [], headers \\ [])
2018-12-04 13:39:08 +00:00
def get("https://osada.macgirvin.com/channel/mike", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com_channel_mike.json"),
headers: activitypub_object_headers()
2018-12-04 13:39:08 +00:00
}}
end
2019-10-18 04:58:28 +01:00
def get("https://shitposter.club/users/moonman", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/moonman@shitposter.club.json"),
headers: activitypub_object_headers()
2019-10-18 04:58:28 +01:00
}}
end
def get("https://mastodon.social/users/emelie/statuses/101849165031453009", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/status.emelie.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mastodon.social/users/emelie/statuses/101849165031453404", _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def get("https://mastodon.social/users/emelie", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/emelie.json"),
headers: activitypub_object_headers()
}}
2019-05-15 18:10:16 +01:00
end
2019-07-31 16:14:36 +01:00
def get("https://mastodon.social/users/not_found", _, _, _) do
{:ok, %Tesla.Env{status: 404}}
end
2019-05-15 18:10:16 +01:00
def get("https://mastodon.sdf.org/users/rinpatch", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rinpatch.json"),
headers: activitypub_object_headers()
2019-05-15 18:10:16 +01:00
}}
end
def get("https://mastodon.sdf.org/users/rinpatch/collections/featured", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
File.read!("test/fixtures/users_mock/masto_featured.json")
|> String.replace("{{domain}}", "mastodon.sdf.org")
|> String.replace("{{nickname}}", "rinpatch"),
headers: activitypub_object_headers()
}}
end
2020-06-23 04:30:34 +01:00
def get("https://patch.cx/objects/tesla_mock/poll_attachment", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_attachment.json"),
headers: activitypub_object_headers()
2020-06-23 04:30:34 +01:00
}}
end
def get(
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/emelie",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/webfinger_emelie.json"),
headers: activitypub_object_headers()
}}
end
2018-12-04 14:48:55 +00:00
def get(
"https://osada.macgirvin.com/.well-known/webfinger?resource=acct:mike@osada.macgirvin.com",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-04 14:48:55 +00:00
) do
2018-12-04 13:39:08 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mike@osada.macgirvin.com.json"),
headers: [{"content-type", "application/jrd+json"}]
2018-12-04 13:39:08 +00:00
}}
end
2018-12-04 14:48:55 +00:00
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/29191",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-04 14:48:55 +00:00
) do
2018-12-04 11:01:39 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/https___social.heldscal.la_user_29191.xml")
2018-12-04 11:01:39 +00:00
}}
end
2018-12-04 14:48:55 +00:00
def get(
"https://pawoo.net/.well-known/webfinger?resource=acct:https://pawoo.net/users/pekorino",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-04 14:48:55 +00:00
) do
2018-12-04 11:01:39 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/https___pawoo.net_users_pekorino.xml")
2018-12-04 11:01:39 +00:00
}}
end
2018-12-04 14:48:55 +00:00
def get(
"https://social.stopwatchingus-heidelberg.de/.well-known/webfinger?resource=acct:https://social.stopwatchingus-heidelberg.de/user/18330",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-04 14:48:55 +00:00
) do
2018-12-04 11:01:39 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/atarifrosch_webfinger.xml")
2018-12-04 11:01:39 +00:00
}}
end
2018-12-04 14:48:55 +00:00
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=nonexistant@social.heldscal.la",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-04 14:48:55 +00:00
) do
2018-12-04 11:01:39 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/nonexistant@social.heldscal.la.xml")
2018-12-04 11:01:39 +00:00
}}
end
2018-12-02 15:17:26 +00:00
2019-01-31 16:30:56 +00:00
def get(
"https://squeet.me/xrd/?uri=acct:lain@squeet.me",
2019-01-31 16:30:56 +00:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-03 18:37:55 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/lain_squeet.me_webfinger.xml"),
headers: [{"content-type", "application/xrd+xml"}]
2018-12-03 18:37:55 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"https://mst3k.interlinked.me/users/luciferMysticus",
_,
_,
@activitypub_accept_headers
2018-12-03 18:37:55 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/lucifermysticus.json"),
headers: activitypub_object_headers()
2018-12-03 18:37:55 +00:00
}}
end
2018-12-03 15:53:22 +00:00
def get("https://prismo.news/@mxb", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___prismo.news__mxb.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"https://hubzilla.example.org/channel/kaniini",
_,
_,
@activitypub_accept_headers
2018-12-03 18:37:55 +00:00
) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/kaniini@hubzilla.example.org.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://niu.moe/users/rye", _, _, @activitypub_accept_headers) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rye.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://n1u.moe/users/rye", _, _, @activitypub_accept_headers) do
2019-06-04 06:46:19 +01:00
{:ok,
%Tesla.Env{
status: 200,
body:
File.read!("test/fixtures/tesla_mock/rye.json")
|> Jason.decode!()
|> Map.put("name", "evil rye")
|> Map.put("bio", "boooo!")
|> Jason.encode!(),
headers: activitypub_object_headers()
2019-06-04 06:46:19 +01:00
}}
end
2018-12-03 15:53:22 +00:00
def get("http://mastodon.example.org/users/admin/statuses/100787282858396771", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2018-12-03 18:37:55 +00:00
body:
File.read!(
2019-07-03 08:42:24 +01:00
"test/fixtures/tesla_mock/http___mastodon.example.org_users_admin_status_1234.json"
2018-12-03 18:37:55 +00:00
)
2018-12-03 15:53:22 +00:00
}}
end
def get("https://puckipedia.com/", _, _, @activitypub_accept_headers) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/puckipedia.com.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://peertube.moe/accounts/7even", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/7even.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://peertube.stream/accounts/createurs", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/peertube/actor-person.json"),
headers: activitypub_object_headers()
}}
end
2018-12-03 15:53:22 +00:00
def get("https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/peertube.moe-vid.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
2020-05-25 12:13:42 +01:00
def get("https://framatube.org/accounts/framasoft", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json"),
headers: activitypub_object_headers()
2020-05-25 12:13:42 +01:00
}}
end
def get("https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/framatube.org-video.json"),
headers: activitypub_object_headers()
2020-05-25 12:13:42 +01:00
}}
end
2020-04-28 07:32:43 +01:00
def get("https://peertube.social/accounts/craigmaloney", _, _, _) do
2020-04-13 04:53:45 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/craigmaloney.json"),
headers: activitypub_object_headers()
2020-04-13 04:53:45 +01:00
}}
end
2020-04-28 07:32:43 +01:00
def get("https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe", _, _, _) do
2020-04-13 04:53:45 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/peertube-social.json"),
headers: activitypub_object_headers()
2020-04-13 04:53:45 +01:00
}}
end
def get(
"https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39",
_,
_,
@activitypub_accept_headers
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mobilizon.org/@tcit", _, _, @activitypub_accept_headers) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json"),
headers: activitypub_object_headers()
}}
end
2018-12-03 15:53:22 +00:00
def get("https://baptiste.gelez.xyz/@/BaptisteGelez", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-user.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-article.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("https://wedistribute.org/wp-json/pterotype/v1/object/85810", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/wedistribute-article.json"),
headers: activitypub_object_headers()
}}
end
def get("https://wedistribute.org/wp-json/pterotype/v1/actor/-blog", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json"),
headers: activitypub_object_headers()
}}
end
2020-02-11 07:12:57 +00:00
def get("http://mastodon.example.org/users/admin", _, _, _) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/admin@mastdon.example.org.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
2024-06-30 04:25:55 +01:00
def get("http://mastodon.example.org/users/admin/main-key", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/admin@mastdon.example.org.json"),
headers: activitypub_object_headers()
}}
end
def get(
"http://mastodon.example.org/users/admin/statuses/99512778738411822/replies?min_id=99512778738411824&page=true",
_,
_,
_
) do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def get("http://mastodon.example.org/users/relay", _, _, @activitypub_accept_headers) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/relay@mastdon.example.org.json"),
headers: activitypub_object_headers()
}}
end
def get("http://mastodon.example.org/users/gargron", _, _, @activitypub_accept_headers) do
2019-06-04 06:46:19 +01:00
{:error, :nxdomain}
end
2019-10-09 17:32:28 +01:00
def get("https://osada.macgirvin.com/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def get("http://mastodon.sdf.org/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta")
}}
end
def get("https://mastodon.sdf.org/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta")
}}
end
def get(
"https://mastodon.sdf.org/.well-known/webfinger?resource=https://mastodon.sdf.org/users/snowdusk",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json")
}}
end
def get("http://mstdn.jp/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta")
}}
end
def get("https://mstdn.jp/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta")
}}
end
def get("https://mstdn.jp/.well-known/webfinger?resource=kpherox@mstdn.jp", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml")
}}
end
def get("http://mamot.fr/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta")
}}
end
def get("https://mamot.fr/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta")
}}
end
def get("http://pawoo.net/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
}}
end
def get("https://pawoo.net/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
}}
end
def get(
"https://pawoo.net/.well-known/webfinger?resource=https://pawoo.net/users/pekorino",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json"),
headers: activitypub_object_headers()
2019-10-09 17:32:28 +01:00
}}
end
def get("http://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta")
}}
end
def get("https://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta")
}}
end
def get("http://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta")
}}
end
def get("https://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta")
}}
end
Only allow exact id matches This protects us from falling for obvious spoofs as from the current upload exploit (unfortunately we can’t reasonably do anything about spoofs with exact matches as was possible via emoji and proxy). Such objects being invalid is supported by the spec, sepcifically sections 3.1 and 3.2: https://www.w3.org/TR/activitypub/#obj-id Anonymous objects are not relevant here (they can only exists within parent objects iiuc) and neither is client-to-server or transient objects (as those cannot be fetched in the first place). This leaves us with the requirement for `id` to (a) exist and (b) be a publicly dereferencable URI from the originating server. This alone does not yet demand strict equivalence, but the spec then further explains objects ought to be fetchable _via their ID_. Meaning an object not retrievable via its ID, is invalid. This reading is supported by the fact, e.g. GoToSocial (recently) and Mastodon (for 6+ years) do already implement such strict ID checks, additionally proving this doesn’t cause federation issues in practice. However, apart from canonical IDs there can also be additional display URLs. *omas first redirect those to their canonical location, but *keys and Mastodon directly serve the AP representation without redirects. Mastodon and GTS deal with this in two different ways, but both constitute an effective countermeasure: - Mastodon: Unless it already is a known AP id, two fetches occur. The first fetch just reads the `id` property and then refetches from the id. The last fetch requires the returned id to exactly match the URL the content was fetched from. (This can be optimised by skipping the second fetch if it already matches) https://github.com/mastodon/mastodon/blob/05eda8d19330a9c27c0cf07de19a87edff269057/app/helpers/jsonld_helper.rb#L168 https://github.com/mastodon/mastodon/commit/63f097979990bf5ba9db848b8a253056bad781af - GTS: Only does a single fetch and then checks if _either_ the id _or_ url property (which can be an object) match the original fetch URL. This relies on implementations always including their display URL as "url" if differing from the id. For actors this is true for all investigated implementations, for posts only Mastodon includes an "url", but it is also the only one with a differing display URL. https://github.com/superseriousbusiness/gotosocial/commit/2bafd7daf542d985ee76d9079a30a602cb7be827#diff-943bbb02c8ac74ac5dc5d20807e561dcdfaebdc3b62b10730f643a20ac23c24fR222 Albeit Mastodon’s refetch offers higher compatibility with theoretical implmentations using either multiple different display URL or not denoting any of them as "url" at all, for now we chose to adopt a GTS-like refetch-free approach to avoid additional implementation concerns wrt to whether redirects should be allowed when fetching a canonical AP id and potential for accidentally loosening some checks (e.g. cross-domain refetches) for one of the fetches. This may be reconsidered in the future.
2024-03-16 00:00:19 +00:00
# Mastodon status via display URL
2019-01-31 16:30:56 +00:00
def get(
"http://mastodon.example.org/@admin/99541947525187367",
_,
_,
2020-02-11 07:12:57 +00:00
_
2018-12-03 18:37:55 +00:00
) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
Only allow exact id matches This protects us from falling for obvious spoofs as from the current upload exploit (unfortunately we can’t reasonably do anything about spoofs with exact matches as was possible via emoji and proxy). Such objects being invalid is supported by the spec, sepcifically sections 3.1 and 3.2: https://www.w3.org/TR/activitypub/#obj-id Anonymous objects are not relevant here (they can only exists within parent objects iiuc) and neither is client-to-server or transient objects (as those cannot be fetched in the first place). This leaves us with the requirement for `id` to (a) exist and (b) be a publicly dereferencable URI from the originating server. This alone does not yet demand strict equivalence, but the spec then further explains objects ought to be fetchable _via their ID_. Meaning an object not retrievable via its ID, is invalid. This reading is supported by the fact, e.g. GoToSocial (recently) and Mastodon (for 6+ years) do already implement such strict ID checks, additionally proving this doesn’t cause federation issues in practice. However, apart from canonical IDs there can also be additional display URLs. *omas first redirect those to their canonical location, but *keys and Mastodon directly serve the AP representation without redirects. Mastodon and GTS deal with this in two different ways, but both constitute an effective countermeasure: - Mastodon: Unless it already is a known AP id, two fetches occur. The first fetch just reads the `id` property and then refetches from the id. The last fetch requires the returned id to exactly match the URL the content was fetched from. (This can be optimised by skipping the second fetch if it already matches) https://github.com/mastodon/mastodon/blob/05eda8d19330a9c27c0cf07de19a87edff269057/app/helpers/jsonld_helper.rb#L168 https://github.com/mastodon/mastodon/commit/63f097979990bf5ba9db848b8a253056bad781af - GTS: Only does a single fetch and then checks if _either_ the id _or_ url property (which can be an object) match the original fetch URL. This relies on implementations always including their display URL as "url" if differing from the id. For actors this is true for all investigated implementations, for posts only Mastodon includes an "url", but it is also the only one with a differing display URL. https://github.com/superseriousbusiness/gotosocial/commit/2bafd7daf542d985ee76d9079a30a602cb7be827#diff-943bbb02c8ac74ac5dc5d20807e561dcdfaebdc3b62b10730f643a20ac23c24fR222 Albeit Mastodon’s refetch offers higher compatibility with theoretical implmentations using either multiple different display URL or not denoting any of them as "url" at all, for now we chose to adopt a GTS-like refetch-free approach to avoid additional implementation concerns wrt to whether redirects should be allowed when fetching a canonical AP id and potential for accidentally loosening some checks (e.g. cross-domain refetches) for one of the fetches. This may be reconsidered in the future.
2024-03-16 00:00:19 +00:00
url: "http://mastodon.example.org/@admin/99541947525187367",
body: File.read!("test/fixtures/mastodon-note-object.json"),
headers: activitypub_object_headers()
}}
end
# same status via its canonical ActivityPub id
def get(
"http://mastodon.example.org/users/admin/statuses/99541947525187367",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
url: "http://mastodon.example.org/users/admin/statuses/99541947525187367",
body: File.read!("test/fixtures/mastodon-note-object.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
def get("http://mastodon.example.org/@admin/99541947525187368", _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
2018-12-03 15:53:22 +00:00
def get("https://shitposter.club/notice/7369654", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/7369654.html")
2018-12-03 15:53:22 +00:00
}}
end
def get("https://mstdn.io/users/mayuutann", _, _, @activitypub_accept_headers) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mayumayu.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"https://mstdn.io/users/mayuutann/statuses/99568293732299394",
_,
_,
@activitypub_accept_headers
2018-12-03 18:37:55 +00:00
) do
2018-12-03 15:53:22 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mayumayupost.json"),
headers: activitypub_object_headers()
2018-12-03 15:53:22 +00:00
}}
end
2020-02-11 07:12:57 +00:00
def get(url, _, _, [{"accept", "application/xrd+xml,application/jrd+json"}])
2018-12-02 19:05:28 +00:00
when url in [
"https://pleroma.soykaf.com/.well-known/webfinger?resource=acct:https://pleroma.soykaf.com/users/lain",
"https://pleroma.soykaf.com/.well-known/webfinger?resource=https://pleroma.soykaf.com/users/lain"
] do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/https___pleroma.soykaf.com_users_lain.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/1",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/https___shitposter.club_user_1.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get("https://testing.pleroma.lol/objects/b319022a-4946-44c5-9de9-34801f95507b", _, _, _) do
{:ok, %Tesla.Env{status: 200}}
end
def get(
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/5381",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/spc_5381_xrd.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get("http://shitposter.club/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/shitposter.club_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get("https://shitposter.club/notice/4027863", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/7369654.html")
2018-12-02 19:05:28 +00:00
}}
end
def get("http://social.sakamoto.gq/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/social.sakamoto.gq_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://social.sakamoto.gq/.well-known/webfinger?resource=https://social.sakamoto.gq/users/eal",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/eal_sakamoto.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get("http://mastodon.social/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/mastodon.social_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/lambadalambda",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body:
2019-07-03 08:42:24 +01:00
File.read!("test/fixtures/tesla_mock/https___mastodon.social_users_lambadalambda.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://mastodon.social/.well-known/webfinger?resource=acct:not_found@mastodon.social",
_,
_,
[{"accept", "application/xrd+xml,application/jrd+json"}]
) do
{:ok, %Tesla.Env{status: 404}}
end
2018-12-02 19:05:28 +00:00
def get("http://gs.example.org/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/gs.example.org_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"http://gs.example.org/.well-known/webfinger?resource=http://gs.example.org:4040/index.php/user/1",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body:
2019-07-03 08:42:24 +01:00
File.read!("test/fixtures/tesla_mock/http___gs.example.org_4040_index.php_user_1.xml")
2018-12-02 19:05:28 +00:00
}}
end
2019-06-04 06:46:19 +01:00
def get(
"http://gs.example.org:4040/index.php/user/1",
_,
_,
@activitypub_accept_headers
2019-06-04 06:46:19 +01:00
) do
{:ok, %Tesla.Env{status: 406, body: ""}}
end
def get("https://squeet.me/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
2019-07-03 08:42:24 +01:00
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/squeet.me_host_meta")}}
2018-12-02 19:05:28 +00:00
end
2019-01-31 16:30:56 +00:00
def get(
"https://squeet.me/xrd?uri=lain@squeet.me",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/lain_squeet.me_webfinger.xml")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=acct:shp@social.heldscal.la",
2018-12-02 19:05:28 +00:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/shp@social.heldscal.la.xml"),
headers: [{"content-type", "application/xrd+xml"}]
2018-12-02 19:05:28 +00:00
}}
end
2019-07-24 16:13:10 +01:00
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=acct:invalid_content@social.heldscal.la",
2019-07-24 16:13:10 +01:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2019-07-24 16:13:10 +01:00
) do
{:ok, %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/jrd+json"}]}}
2019-07-24 16:13:10 +01:00
end
def get("https://framatube.org/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/framatube.org_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"https://framatube.org/main/xrd?uri=acct:framasoft@framatube.org",
2019-01-31 16:30:56 +00:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-type", "application/jrd+json"}],
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/framasoft@framatube.org.json")
2018-12-02 19:05:28 +00:00
}}
end
def get("http://gnusocial.de/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/gnusocial.de_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"http://gnusocial.de/main/xrd?uri=winterdienst@gnusocial.de",
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/winterdienst_webfinger.json"),
headers: activitypub_object_headers()
2018-12-02 19:05:28 +00:00
}}
end
def get("https://status.alpicola.com/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/status.alpicola.com_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get("https://macgirvin.com/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/macgirvin.com_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
def get("https://gerzilla.de/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/gerzilla.de_host_meta")
2018-12-02 19:05:28 +00:00
}}
end
2019-01-31 16:30:56 +00:00
def get(
"https://gerzilla.de/xrd/?uri=acct:kaniini@gerzilla.de",
2019-01-31 16:30:56 +00:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2018-12-02 19:05:28 +00:00
) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-type", "application/jrd+json"}],
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/kaniini@gerzilla.de.json")
2018-12-02 19:05:28 +00:00
}}
end
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/23211",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/https___social.heldscal.la_user_23211.xml")
2018-12-02 19:05:28 +00:00
}}
2018-12-02 15:17:26 +00:00
end
def get("http://social.heldscal.la/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/social.heldscal.la_host_meta")
2018-12-02 19:05:28 +00:00
}}
2018-12-02 15:17:26 +00:00
end
def get("https://social.heldscal.la/.well-known/host-meta", _, _, _) do
2018-12-02 19:05:28 +00:00
{:ok,
%Tesla.Env{
status: 200,
2019-07-03 08:42:24 +01:00
body: File.read!("test/fixtures/tesla_mock/social.heldscal.la_host_meta")
2018-12-02 19:05:28 +00:00
}}
2018-12-02 15:17:26 +00:00
end
def get("https://mastodon.social/users/lambadalambda", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/lambadalambda.json"),
headers: activitypub_object_headers()
}}
end
2024-06-30 04:25:55 +01:00
def get("https://mastodon.social/users/lambadalambda#main-key", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/lambadalambda.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mastodon.social/users/lambadalambda/collections/featured", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
File.read!("test/fixtures/users_mock/masto_featured.json")
|> String.replace("{{domain}}", "mastodon.social")
|> String.replace("{{nickname}}", "lambadalambda"),
headers: activitypub_object_headers()
}}
end
def get("https://apfed.club/channel/indio", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json"),
headers: activitypub_object_headers()
}}
end
def get("https://social.heldscal.la/user/23211", _, _, @activitypub_accept_headers) do
2018-12-02 19:05:28 +00:00
{:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)}
2018-12-02 15:17:26 +00:00
end
def get("http://example.com/ogp", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}
end
def get("https://example.com/ogp", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}
end
def get("https://pleroma.local/notice/9kCP7V", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}
end
def get("http://remote.org/users/masto_closed/followers", _, _, _) do
2019-07-09 18:36:35 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_followers.json"),
headers: activitypub_object_headers()
2019-07-09 18:36:35 +01:00
}}
end
def get("http://remote.org/users/masto_closed/followers?page=1", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_followers_page.json"),
headers: activitypub_object_headers()
}}
end
def get("http://remote.org/users/masto_closed/following", _, _, _) do
2019-07-09 18:36:35 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_following.json"),
headers: activitypub_object_headers()
2019-07-09 18:36:35 +01:00
}}
end
def get("http://remote.org/users/masto_closed/following?page=1", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_following_page.json"),
headers: activitypub_object_headers()
}}
end
2019-11-30 06:24:08 +00:00
def get("http://remote.org/followers/fuser3", _, _, _) do
2019-11-30 06:24:08 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/friendica_followers.json"),
headers: activitypub_object_headers()
2019-11-30 06:24:08 +00:00
}}
end
def get("http://remote.org/following/fuser3", _, _, _) do
2019-11-30 06:24:08 +00:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/friendica_following.json"),
headers: activitypub_object_headers()
2019-11-30 06:24:08 +00:00
}}
end
def get("http://remote.org/users/fuser2/followers", _, _, _) do
2019-07-09 18:36:35 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/pleroma_followers.json"),
headers: activitypub_object_headers()
2019-07-09 18:36:35 +01:00
}}
end
def get("http://remote.org/users/fuser2/following", _, _, _) do
2019-07-09 18:36:35 +01:00
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/pleroma_following.json"),
headers: activitypub_object_headers()
2019-07-09 18:36:35 +01:00
}}
end
def get("http://domain-with-errors:4001/users/fuser1/followers", _, _, _) do
{:ok,
%Tesla.Env{
status: 504,
body: ""
}}
end
def get("http://domain-with-errors:4001/users/fuser1/following", _, _, _) do
{:ok,
%Tesla.Env{
status: 504,
body: ""
}}
end
def get("http://example.com/ogp-missing-data", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/rich_media/ogp-missing-data.html")
}}
end
def get("https://example.com/ogp-missing-data", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/rich_media/ogp-missing-data.html")
}}
end
2019-01-31 16:12:35 +00:00
def get("http://example.com/malformed", _, _, _) do
2019-01-31 16:30:56 +00:00
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}}
2019-01-31 16:12:35 +00:00
end
def get("http://example.com/empty", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: "hello"}}
end
def get("http://404.site" <> _, _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def get("https://404.site" <> _, _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
2019-07-10 16:23:25 +01:00
def get(
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:lain@zetsubou.xn--q9jyb4c",
2019-07-10 16:23:25 +01:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2019-07-10 16:23:25 +01:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/lain.xml"),
headers: [{"content-type", "application/xrd+xml"}]
2019-07-10 16:23:25 +01:00
}}
end
def get(
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:https://zetsubou.xn--q9jyb4c/users/lain",
2019-07-10 16:23:25 +01:00
_,
_,
2020-02-11 07:12:57 +00:00
[{"accept", "application/xrd+xml,application/jrd+json"}]
2019-07-10 16:23:25 +01:00
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/lain.xml"),
headers: [{"content-type", "application/xrd+xml"}]
}}
end
def get("http://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/host-meta-zetsubou.xn--q9jyb4c.xml")
2019-07-10 16:23:25 +01:00
}}
end
def get(
"https://zetsubou.xn--q9jyb4c/.well-known/host-meta",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/host-meta-zetsubou.xn--q9jyb4c.xml")
}}
end
def get("http://lm.kazv.moe/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/lm.kazv.moe_host_meta")
}}
end
def get("https://lm.kazv.moe/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/lm.kazv.moe_host_meta")
}}
end
def get(
"https://lm.kazv.moe/.well-known/webfinger?resource=acct:mewmew@lm.kazv.moe",
_,
_,
[{"accept", "application/xrd+xml,application/jrd+json"}]
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml"),
headers: [{"content-type", "application/xrd+xml"}]
}}
end
def get("https://lm.kazv.moe/users/mewmew", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json"),
headers: activitypub_object_headers()
}}
end
def get("https://lm.kazv.moe/users/mewmew/collections/featured", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
File.read!("test/fixtures/users_mock/masto_featured.json")
|> String.replace("{{domain}}", "lm.kazv.moe")
|> String.replace("{{nickname}}", "mewmew"),
headers: activitypub_object_headers()
}}
end
def get("https://info.pleroma.site/activity.json", _, _, @activitypub_accept_headers) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity.json"),
headers: activitypub_object_headers()
}}
end
def get("https://info.pleroma.site/activity.json", _, _, _) do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def get("https://info.pleroma.site/activity2.json", _, _, @activitypub_accept_headers) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity2.json"),
headers: activitypub_object_headers()
}}
end
def get("https://info.pleroma.site/activity2.json", _, _, _) do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def get("https://info.pleroma.site/activity3.json", _, _, @activitypub_accept_headers) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity3.json"),
headers: activitypub_object_headers()
}}
end
def get("https://info.pleroma.site/activity3.json", _, _, _) do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
2019-07-24 17:27:34 +01:00
def get("https://mstdn.jp/.well-known/webfinger?resource=acct:kpherox@mstdn.jp", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml"),
headers: [{"content-type", "application/xrd+xml"}]
2019-07-24 17:27:34 +01:00
}}
end
2019-11-04 15:18:32 +00:00
def get("https://10.111.10.1/notice/9kCP7V", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: ""}}
end
def get("https://172.16.32.40/notice/9kCP7V", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: ""}}
end
def get("https://192.168.10.40/notice/9kCP7V", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: ""}}
end
def get("https://www.patreon.com/posts/mastodon-2-9-and-28121681", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: ""}}
end
def get("http://mastodon.example.org/@admin/99541947525187367", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-post-activity.json"),
headers: activitypub_object_headers()
}}
2019-11-04 15:18:32 +00:00
end
def get("https://info.pleroma.site/activity4.json", _, _, _) do
{:ok, %Tesla.Env{status: 500, body: "Error occurred"}}
end
2019-08-25 07:03:25 +01:00
def get("http://example.com/rel_me/anchor", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")}}
end
def get("http://example.com/rel_me/anchor_nofollow", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor_nofollow.html")}}
end
def get("http://example.com/rel_me/link", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")}}
end
def get("http://example.com/rel_me/null", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}}
end
def get("https://skippers-bin.com/notes/7x9tmrp97i", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json"),
headers: activitypub_object_headers()
}}
end
2024-04-13 23:05:52 +01:00
# A misskey quote
def get("https://misskey.io/notes/8vs6wxufd0", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json"),
headers: activitypub_object_headers()
}}
end
def get("https://misskey.io/users/83ssedkv53", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/aimu@misskey.io.json"),
headers: activitypub_object_headers()
}}
end
def get("https://example.org/emoji/firedfox.png", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}}
end
def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/sjw.json"),
headers: activitypub_object_headers()
}}
end
def get("https://patch.cx/users/rin", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rin.json"),
headers: activitypub_object_headers()
}}
end
def get(
"https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/funkwhale_audio.json"),
headers: activitypub_object_headers()
}}
end
def get("https://channels.tests.funkwhale.audio/federation/actors/compositions", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json"),
headers: activitypub_object_headers()
}}
end
2019-11-04 15:18:32 +00:00
def get("http://example.com/rel_me/error", _, _, _) do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def get("https://relay.mastodon.host/actor", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/relay/relay.json"),
headers: activitypub_object_headers()
}}
end
2024-06-30 04:25:55 +01:00
def get("https://relay.mastodon.host/actor#main-key", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/relay/relay.json"),
headers: activitypub_object_headers()
}}
end
def get("http://localhost:4001/", _, "", [{"accept", "text/html"}]) do
2020-03-01 08:48:32 +00:00
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}}
end
def get("https://osada.macgirvin.com/", _, "", [{"accept", "text/html"}]) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com.html")
}}
end
def get("https://patch.cx/objects/a399c28e-c821-4820-bc3e-4afeb044c16f", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/emoji-in-summary.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mk.absturztau.be/users/8ozbzjs3o8", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json"),
headers: activitypub_object_headers()
}}
end
def get("https://p.helene.moe/users/helene", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/helene@p.helene.moe.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mk.absturztau.be/notes/93e7nm8wqg", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mk.absturztau.be/notes/93e7nm8wqg/activity", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"),
headers: activitypub_object_headers()
}}
end
def get("https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json"),
headers: activitypub_object_headers()
}}
end
def get("https://google.com/", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/google.html")}}
end
def get("https://yahoo.com/", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/yahoo.html")}}
end
def get("https://example.com/error", _, _, _), do: {:error, :overload}
def get("https://example.com/ogp-missing-title", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/rich_media/ogp-missing-title.html")
}}
end
def get("https://example.com/oembed", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.html")}}
end
def get("https://example.com/oembed.json", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.json")}}
end
def get("https://example.com/twitter-card", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}}
end
def get("https://example.com/non-ogp", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/non_ogp_embed.html")}}
end
def get("https://example.com/empty", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: "hello"}}
end
def get("https://friends.grishka.me/posts/54642", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/smithereen_non_anonymous_poll.json"),
headers: activitypub_object_headers()
}}
end
def get("https://friends.grishka.me/users/1", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/smithereen_user.json"),
headers: activitypub_object_headers()
}}
end
def get("https://mastodon.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 302,
headers: [{"location", "https://sub.mastodon.example/.well-known/host-meta"}]
}}
end
def get("https://sub.mastodon.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/masto-host-meta.xml"
|> File.read!()
|> String.replace("{{domain}}", "sub.mastodon.example")
}}
end
def get(
"https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/masto-webfinger.json"
|> File.read!()
|> String.replace("{{nickname}}", "a")
|> String.replace("{{domain}}", "mastodon.example")
|> String.replace("{{subdomain}}", "sub.mastodon.example"),
headers: [{"content-type", "application/jrd+json"}]
}}
end
def get("https://sub.mastodon.example/users/a", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/masto-user.json"
|> File.read!()
|> String.replace("{{nickname}}", "a")
|> String.replace("{{domain}}", "sub.mastodon.example"),
headers: [{"content-type", "application/activity+json"}]
}}
end
def get("https://sub.mastodon.example/users/a/collections/featured", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
File.read!("test/fixtures/users_mock/masto_featured.json")
|> String.replace("{{domain}}", "sub.mastodon.example")
|> String.replace("{{nickname}}", "a"),
headers: [{"content-type", "application/activity+json"}]
}}
end
def get("https://pleroma.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 302,
headers: [{"location", "https://sub.pleroma.example/.well-known/host-meta"}]
}}
end
def get("https://sub.pleroma.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/pleroma-host-meta.xml"
|> File.read!()
|> String.replace("{{domain}}", "sub.pleroma.example")
}}
end
def get(
"https://sub.pleroma.example/.well-known/webfinger?resource=acct:a@pleroma.example",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/pleroma-webfinger.json"
|> File.read!()
|> String.replace("{{nickname}}", "a")
|> String.replace("{{domain}}", "pleroma.example")
|> String.replace("{{subdomain}}", "sub.pleroma.example"),
headers: [{"content-type", "application/jrd+json"}]
}}
end
def get("https://sub.pleroma.example/users/a", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body:
"test/fixtures/webfinger/pleroma-user.json"
|> File.read!()
|> String.replace("{{nickname}}", "a")
|> String.replace("{{domain}}", "sub.pleroma.example"),
headers: [{"content-type", "application/activity+json"}]
}}
end
2018-12-02 15:17:26 +00:00
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
2018-12-02 15:17:26 +00:00
end
# POST Requests
#
def post(url, query \\ [], body \\ [], headers \\ [])
def post("https://relay.mastodon.host/inbox", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: ""}}
end
2018-12-02 15:17:26 +00:00
def post("http://example.org/needs_refresh", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: ""
}}
end
def post("http://mastodon.example.org/inbox", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: ""
}}
end
def post("https://hubzilla.example.org/inbox", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: ""
}}
end
def post("http://gs.example.org/index.php/main/salmon/user/1", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: ""
}}
end
def post("http://200.site" <> _, _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: ""
}}
end
def post("http://connrefused.site" <> _, _, _, _) do
{:error, :connrefused}
end
def post("http://404.site" <> _, _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def post(url, query, body, headers) do
{:error,
"Mock response not implemented for POST #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
2018-12-02 15:17:26 +00:00
end
# Most of the rich media mocks are missing HEAD requests, so we just return 404.
@rich_media_mocks [
2024-06-09 18:28:00 +01:00
"https://example.com/empty",
"https://example.com/error",
"https://example.com/malformed",
"https://example.com/non-ogp",
"https://example.com/oembed",
"https://example.com/oembed.json",
"https://example.com/ogp",
"https://example.com/ogp-missing-data",
2024-06-09 18:28:00 +01:00
"https://example.com/ogp-missing-title",
"https://example.com/twitter-card",
"https://google.com/",
"https://pleroma.local/notice/9kCP7V",
"https://yahoo.com/"
]
2024-06-09 18:28:00 +01:00
def head(url, _query, _body, _headers) when url in @rich_media_mocks do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
2024-06-09 18:28:00 +01:00
def head("https://example.com/pdf-file", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-length", "1000000"}, {"content-type", "application/pdf"}]
}}
end
def head("https://example.com/huge-page", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-length", "2000001"}, {"content-type", "text/html"}]
}}
end
def head(url, query, body, headers) do
{:error,
"Mock response not implemented for HEAD #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
end
2018-12-02 15:17:26 +00:00
end