Harden M3 giftwrap recipient gating in storage adapters
This commit is contained in:
@@ -37,15 +37,19 @@ defmodule Parrhesia.Storage.Adapters.Memory.Events do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def query(_context, filters, _opts) do
|
def query(_context, filters, opts) do
|
||||||
with :ok <- Filter.validate_filters(filters) do
|
with :ok <- Filter.validate_filters(filters) do
|
||||||
state = Store.get(& &1)
|
state = Store.get(& &1)
|
||||||
|
requester_pubkeys = Keyword.get(opts, :requester_pubkeys, [])
|
||||||
|
|
||||||
events =
|
events =
|
||||||
state.events
|
state.events
|
||||||
|> Map.values()
|
|> Map.values()
|
||||||
|> Enum.reject(fn event -> MapSet.member?(state.deleted, event["id"]) end)
|
|> Enum.filter(fn event ->
|
||||||
|> Enum.filter(&Filter.matches_any?(&1, filters))
|
not MapSet.member?(state.deleted, event["id"]) and
|
||||||
|
Filter.matches_any?(event, filters) and
|
||||||
|
giftwrap_visible_to_requester?(event, requester_pubkeys)
|
||||||
|
end)
|
||||||
|
|
||||||
{:ok, events}
|
{:ok, events}
|
||||||
end
|
end
|
||||||
@@ -100,4 +104,20 @@ defmodule Parrhesia.Storage.Adapters.Memory.Events do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def purge_expired(_opts), do: {:ok, 0}
|
def purge_expired(_opts), do: {:ok, 0}
|
||||||
|
|
||||||
|
defp giftwrap_visible_to_requester?(%{"kind" => 1059} = event, requester_pubkeys) do
|
||||||
|
requester_pubkeys != [] and
|
||||||
|
event_targets_any_recipient?(event, requester_pubkeys)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp giftwrap_visible_to_requester?(_event, _requester_pubkeys), do: true
|
||||||
|
|
||||||
|
defp event_targets_any_recipient?(event, requester_pubkeys) do
|
||||||
|
event
|
||||||
|
|> Map.get("tags", [])
|
||||||
|
|> Enum.any?(fn
|
||||||
|
["p", recipient | _rest] -> recipient in requester_pubkeys
|
||||||
|
_tag -> false
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -661,7 +661,8 @@ defmodule Parrhesia.Storage.Adapters.Postgres.Events do
|
|||||||
defp maybe_restrict_giftwrap_access(query, filter, opts) do
|
defp maybe_restrict_giftwrap_access(query, filter, opts) do
|
||||||
requester_pubkeys = Keyword.get(opts, :requester_pubkeys, [])
|
requester_pubkeys = Keyword.get(opts, :requester_pubkeys, [])
|
||||||
|
|
||||||
if targets_giftwrap?(filter) and requester_pubkeys != [] do
|
cond do
|
||||||
|
targets_giftwrap?(filter) and requester_pubkeys != [] ->
|
||||||
where(
|
where(
|
||||||
query,
|
query,
|
||||||
[event],
|
[event],
|
||||||
@@ -672,7 +673,11 @@ defmodule Parrhesia.Storage.Adapters.Postgres.Events do
|
|||||||
type(^requester_pubkeys, {:array, :string})
|
type(^requester_pubkeys, {:array, :string})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else
|
|
||||||
|
targets_giftwrap?(filter) ->
|
||||||
|
where(query, [_event], false)
|
||||||
|
|
||||||
|
true ->
|
||||||
query
|
query
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -25,4 +25,26 @@ defmodule Parrhesia.Storage.Adapters.Memory.AdapterTest do
|
|||||||
assert :ok = Admin.append_audit_log(%{}, %{method: "ping"})
|
assert :ok = Admin.append_audit_log(%{}, %{method: "ping"})
|
||||||
assert {:ok, [%{method: "ping"}]} = Admin.list_audit_logs(%{}, [])
|
assert {:ok, [%{method: "ping"}]} = Admin.list_audit_logs(%{}, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "memory adapter enforces recipient visibility for giftwrap queries" do
|
||||||
|
recipient = String.duplicate("b", 64)
|
||||||
|
|
||||||
|
giftwrap_event = %{
|
||||||
|
"id" => String.duplicate("c", 64),
|
||||||
|
"pubkey" => "pk",
|
||||||
|
"kind" => 1059,
|
||||||
|
"tags" => [["p", recipient]],
|
||||||
|
"content" => "ciphertext"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, _event} = Events.put_event(%{}, giftwrap_event)
|
||||||
|
|
||||||
|
filters = [%{"kinds" => [1059], "#p" => [recipient]}]
|
||||||
|
|
||||||
|
assert {:ok, [result]} = Events.query(%{}, filters, requester_pubkeys: [recipient])
|
||||||
|
assert result["id"] == giftwrap_event["id"]
|
||||||
|
|
||||||
|
assert {:ok, []} = Events.query(%{}, filters, requester_pubkeys: [])
|
||||||
|
assert {:ok, 0} = Events.count(%{}, filters, requester_pubkeys: [])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -243,6 +243,9 @@ defmodule Parrhesia.Storage.Adapters.Postgres.EventsQueryCountTest do
|
|||||||
Events.query(%{}, filters, requester_pubkeys: [recipient])
|
Events.query(%{}, filters, requester_pubkeys: [recipient])
|
||||||
|
|
||||||
assert result["id"] == allowed["id"]
|
assert result["id"] == allowed["id"]
|
||||||
|
|
||||||
|
assert {:ok, []} = Events.query(%{}, filters, requester_pubkeys: [])
|
||||||
|
assert {:ok, 0} = Events.count(%{}, filters, requester_pubkeys: [])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "query/3 supports #i keypackage reference lookups" do
|
test "query/3 supports #i keypackage reference lookups" do
|
||||||
|
|||||||
Reference in New Issue
Block a user