fetcher: split out core object fetch validation
To allow reuse for adapted key validation logic
This commit is contained in:
parent
b5fa8c6d09
commit
366065c0f6
1 changed files with 29 additions and 12 deletions
|
@ -265,6 +265,28 @@ def fetch_and_contain_remote_object_from_id(%{"id" => id}, is_ap_id),
|
|||
def fetch_and_contain_remote_object_from_id(id, is_ap_id) when is_binary(id) do
|
||||
Logger.debug("Fetching object #{id} via AP [ap_id=#{is_ap_id}]")
|
||||
|
||||
fetch_and_contain_remote_ap_doc(
|
||||
id,
|
||||
is_ap_id,
|
||||
fn final_uri, data -> {Containment.contain_id_to_fetch(final_uri, data), data["id"]} end
|
||||
)
|
||||
end
|
||||
|
||||
def fetch_and_contain_remote_object_from_id(_id, _is_ap_id),
|
||||
do: {:error, :invalid_id}
|
||||
|
||||
# Fetches an AP document and performing variable security checks on it.
|
||||
#
|
||||
# Note that the received documents "id" matching the final host domain
|
||||
# is always enforced before the custom ID check runs.
|
||||
@spec fetch_and_contain_remote_ap_doc(
|
||||
String.t(),
|
||||
boolean(),
|
||||
(String.t(), Map.t() -> {:ok | :error, String.t() | term()})
|
||||
) :: {:ok, Map.t()} | {:reject, term()} | {:error, term()}
|
||||
defp fetch_and_contain_remote_ap_doc(id, is_ap_id, verify_id) do
|
||||
Logger.debug("Dereferencing AP doc #{}")
|
||||
|
||||
with {:valid_uri_scheme, true} <- {:valid_uri_scheme, String.starts_with?(id, "http")},
|
||||
%URI{} = uri <- URI.parse(id),
|
||||
{:mrf_reject_check, {:ok, nil}} <-
|
||||
|
@ -277,7 +299,7 @@ def fetch_and_contain_remote_object_from_id(id, is_ap_id) when is_binary(id) do
|
|||
true <- !is_ap_id || final_id == id,
|
||||
{:ok, data} <- safe_json_decode(body),
|
||||
{_, :ok} <- {:containment, Containment.contain_origin(final_id, data)},
|
||||
{_, _, :ok} <- {:strict_id, data["id"], Containment.contain_id_to_fetch(final_id, data)} do
|
||||
{_, {:ok, _}} <- {:strict_id, verify_id.(final_id, data)} do
|
||||
unless Instances.reachable?(final_id) do
|
||||
Instances.set_reachable(final_id)
|
||||
end
|
||||
|
@ -289,14 +311,12 @@ def fetch_and_contain_remote_object_from_id(id, is_ap_id) when is_binary(id) do
|
|||
# Similarly keys, either use a fragment ID and are a subobjects or a distinct ID
|
||||
# but for compatibility are still a subobject presenting their owning actors ID at the toplevel.
|
||||
# Refetching _once_ from the listed id, should yield a strict match afterwards.
|
||||
{:strict_id, ap_id, _} = e ->
|
||||
case is_ap_id do
|
||||
false ->
|
||||
fetch_and_contain_remote_object_from_id(ap_id, true)
|
||||
|
||||
true ->
|
||||
log_fetch_error(id, e)
|
||||
{:error, :id_mismatch}
|
||||
{:strict_id, {_error, ap_id}} = e ->
|
||||
if !is_ap_id and is_binary(ap_id) do
|
||||
fetch_and_contain_remote_ap_doc(ap_id, true, verify_id)
|
||||
else
|
||||
log_fetch_error(id, e)
|
||||
{:error, :id_mismatch}
|
||||
end
|
||||
|
||||
{:mrf_reject_check, _} = e ->
|
||||
|
@ -327,9 +347,6 @@ def fetch_and_contain_remote_object_from_id(id, is_ap_id) when is_binary(id) do
|
|||
end
|
||||
end
|
||||
|
||||
def fetch_and_contain_remote_object_from_id(_id, _is_ap_id),
|
||||
do: {:error, :invalid_id}
|
||||
|
||||
# HOPEFULLY TEMPORARY
|
||||
# Basically none of our Tesla mocks in tests set the (supposed to
|
||||
# exist for Tesla proper) url parameter for their responses
|
||||
|
|
Loading…
Reference in a new issue