forked from potsda.mn/mobilizon
fix(nodeinfo): make sure we only process JSON content
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
881695ca19
commit
da3b074619
|
@ -5,6 +5,7 @@ defmodule Mobilizon.Federation.NodeInfo do
|
||||||
|
|
||||||
alias Mobilizon.Service.HTTP.WebfingerClient
|
alias Mobilizon.Service.HTTP.WebfingerClient
|
||||||
require Logger
|
require Logger
|
||||||
|
import Mobilizon.Service.HTTP.Utils, only: [is_content_type?: 2]
|
||||||
|
|
||||||
@application_uri "https://www.w3.org/ns/activitystreams#Application"
|
@application_uri "https://www.w3.org/ns/activitystreams#Application"
|
||||||
@nodeinfo_rel_2_0 "http://nodeinfo.diaspora.software/ns/schema/2.0"
|
@nodeinfo_rel_2_0 "http://nodeinfo.diaspora.software/ns/schema/2.0"
|
||||||
|
@ -31,7 +32,9 @@ defmodule Mobilizon.Federation.NodeInfo do
|
||||||
|
|
||||||
with {:ok, endpoint} when is_binary(endpoint) <- fetch_nodeinfo_details(host),
|
with {:ok, endpoint} when is_binary(endpoint) <- fetch_nodeinfo_details(host),
|
||||||
:ok <- Logger.debug("Going to get NodeInfo information from URL #{endpoint}"),
|
:ok <- Logger.debug("Going to get NodeInfo information from URL #{endpoint}"),
|
||||||
{:ok, %{body: body, status: code}} when code in 200..299 <- WebfingerClient.get(endpoint) do
|
{:ok, %{body: body, status: code, headers: headers}} when code in 200..299 <-
|
||||||
|
WebfingerClient.get(endpoint),
|
||||||
|
{:ok, body} <- validate_json_response(body, headers) do
|
||||||
Logger.debug("Found nodeinfo information for domain #{host}")
|
Logger.debug("Found nodeinfo information for domain #{host}")
|
||||||
{:ok, body}
|
{:ok, body}
|
||||||
else
|
else
|
||||||
|
@ -58,8 +61,8 @@ defmodule Mobilizon.Federation.NodeInfo do
|
||||||
prefix = if @env !== :dev, do: "https", else: "http"
|
prefix = if @env !== :dev, do: "https", else: "http"
|
||||||
|
|
||||||
case WebfingerClient.get("#{prefix}://#{host}/.well-known/nodeinfo") do
|
case WebfingerClient.get("#{prefix}://#{host}/.well-known/nodeinfo") do
|
||||||
{:ok, %{body: body, status: code}} when code in 200..299 ->
|
{:ok, %{body: body, status: code, headers: headers}} when code in 200..299 ->
|
||||||
{:ok, body}
|
validate_json_response(body, headers)
|
||||||
|
|
||||||
err ->
|
err ->
|
||||||
Logger.debug("Failed to fetch NodeInfo data #{inspect(err)}")
|
Logger.debug("Failed to fetch NodeInfo data #{inspect(err)}")
|
||||||
|
@ -102,4 +105,19 @@ defmodule Mobilizon.Federation.NodeInfo do
|
||||||
rel == relation and is_binary(href)
|
rel == relation and is_binary(href)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_json_response(map() | String.t(), list()) ::
|
||||||
|
{:ok, String.t()} | {:error, :bad_content_type | :body_not_json}
|
||||||
|
defp validate_json_response(body, headers) do
|
||||||
|
cond do
|
||||||
|
!is_content_type?(headers, "application/json") ->
|
||||||
|
{:error, :bad_content_type}
|
||||||
|
|
||||||
|
!is_map(body) ->
|
||||||
|
{:error, :body_not_json}
|
||||||
|
|
||||||
|
true ->
|
||||||
|
{:ok, body}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,7 +24,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://event-federation.eu/.well-known/nodeinfo"
|
url: "https://event-federation.eu/.well-known/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert "https://event-federation.eu/actor-relay" ==
|
assert "https://event-federation.eu/actor-relay" ==
|
||||||
|
@ -76,7 +81,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://mobilizon.fr/.well-known/nodeinfo"
|
url: "https://mobilizon.fr/.well-known/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_end_point_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_end_point_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
WebfingerClientMock
|
WebfingerClientMock
|
||||||
|
@ -86,7 +96,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://mobilizon.fr/.well-known/nodeinfo/2.1"
|
url: "https://mobilizon.fr/.well-known/nodeinfo/2.1"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:ok, data} = NodeInfo.nodeinfo("mobilizon.fr")
|
assert {:ok, data} = NodeInfo.nodeinfo("mobilizon.fr")
|
||||||
|
@ -107,7 +122,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://event-federation.eu/.well-known/nodeinfo"
|
url: "https://event-federation.eu/.well-known/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_end_point_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_end_point_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
WebfingerClientMock
|
WebfingerClientMock
|
||||||
|
@ -117,7 +137,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://event-federation.eu/wp-json/activitypub/1.0/nodeinfo"
|
url: "https://event-federation.eu/wp-json/activitypub/1.0/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_wp_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_wp_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:ok, data} = NodeInfo.nodeinfo("event-federation.eu")
|
assert {:ok, data} = NodeInfo.nodeinfo("event-federation.eu")
|
||||||
|
@ -138,7 +163,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://somewhere.tld/.well-known/nodeinfo"
|
url: "https://somewhere.tld/.well-known/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_end_point_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_end_point_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:error, :no_node_info_endpoint_found} = NodeInfo.nodeinfo("somewhere.tld")
|
assert {:error, :no_node_info_endpoint_found} = NodeInfo.nodeinfo("somewhere.tld")
|
||||||
|
@ -169,7 +199,12 @@ defmodule Mobilizon.Federation.NodeInfoTest do
|
||||||
url: "https://mobilizon.fr/.well-known/nodeinfo"
|
url: "https://mobilizon.fr/.well-known/nodeinfo"
|
||||||
},
|
},
|
||||||
_opts ->
|
_opts ->
|
||||||
{:ok, %Tesla.Env{status: 200, body: nodeinfo_end_point_data}}
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: nodeinfo_end_point_data,
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
WebfingerClientMock
|
WebfingerClientMock
|
||||||
|
|
|
@ -5,7 +5,6 @@ defmodule Mobilizon.Service.Workers.RefreshInstancesTest do
|
||||||
|
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Federation.ActivityPub.Relay
|
alias Mobilizon.Federation.ActivityPub.Relay
|
||||||
alias Mobilizon.Instances.Instance
|
|
||||||
alias Mobilizon.Service.Workers.RefreshInstances
|
alias Mobilizon.Service.Workers.RefreshInstances
|
||||||
|
|
||||||
use Mobilizon.DataCase
|
use Mobilizon.DataCase
|
||||||
|
@ -14,7 +13,7 @@ defmodule Mobilizon.Service.Workers.RefreshInstancesTest do
|
||||||
test "unless if local actor" do
|
test "unless if local actor" do
|
||||||
# relay = Mobilizon.Web.Relay.get_actor()
|
# relay = Mobilizon.Web.Relay.get_actor()
|
||||||
assert {:error, :not_remote_instance} ==
|
assert {:error, :not_remote_instance} ==
|
||||||
RefreshInstances.refresh_instance_actor(%Instance{domain: nil})
|
RefreshInstances.refresh_instance_actor(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "unless if local relay actor" do
|
test "unless if local relay actor" do
|
||||||
|
@ -22,7 +21,7 @@ defmodule Mobilizon.Service.Workers.RefreshInstancesTest do
|
||||||
%URI{host: domain} = URI.new!(url)
|
%URI{host: domain} = URI.new!(url)
|
||||||
|
|
||||||
assert {:error, :not_remote_instance} ==
|
assert {:error, :not_remote_instance} ==
|
||||||
RefreshInstances.refresh_instance_actor(%Instance{domain: domain})
|
RefreshInstances.refresh_instance_actor(domain)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue