# Copyright 2019 Hubert Chathi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. defmodule Polyjuice.Util.Event do @moduledoc """ Event-related functions. """ defmodule Module.concat(Polyjuice.Util.Event.RoomVersion, "1") do @moduledoc false # the common keys that should be kept in the top level of all events # (except for "content", which has special handling). @keys_to_keep ~w( event_id type room_id sender state_key hashes signatures depth prev_events prev_state auth_events origin origin_server_ts membership ) def redact(event) do redacted_no_content = Map.take(event, @keys_to_keep) with {:ok, content} <- Map.fetch(event, "content"), {:ok, type} <- Map.fetch(event, "type") do content_keys_to_keep = case type do "m.room.member" -> ~w(membership) "m.room.create" -> ~w(creator) "m.room.join_rules" -> ~w(join_rule) "m.room.power_levels" -> ~w(ban events events_default kick redact state_default users users_default) "m.room.aliases" -> ~w(aliases) "m.room.history_visibility" -> ~w(history_visibility) _ -> [] end Map.put( redacted_no_content, "content", Map.take(content, content_keys_to_keep) ) else _ -> redacted_no_content end end end defmodule Module.concat(Polyjuice.Util.Event.RoomVersion, "2") do @moduledoc false defdelegate redact(event), to: Module.concat(Polyjuice.Util.Event.RoomVersion, "1") end defmodule Module.concat(Polyjuice.Util.Event.RoomVersion, "3") do @moduledoc false defdelegate redact(event), to: Module.concat(Polyjuice.Util.Event.RoomVersion, "1") end defmodule Module.concat(Polyjuice.Util.Event.RoomVersion, "4") do @moduledoc false defdelegate redact(event), to: Module.concat(Polyjuice.Util.Event.RoomVersion, "1") end defmodule Module.concat(Polyjuice.Util.Event.RoomVersion, "5") do @moduledoc false defdelegate redact(event), to: Module.concat(Polyjuice.Util.Event.RoomVersion, "1") end @doc ~S""" Calculate the redacted version of an event for the given room version. Examples: iex> Polyjuice.Util.Event.redact( ...> "1", ...> %{ ...> "content" => %{ ...> "body" => "Here is the message content" ...> }, ...> "event_id" => "$0:domain", ...> "origin" => "domain", ...> "origin_server_ts" => 1000000, ...> "type" => "m.room.message", ...> "room_id" => "!r:domain", ...> "sender" => "@u:domain", ...> "signatures" => %{}, ...> "unsigned" => %{ ...> "age_ts" => 1000000 ...> } ...> } ...> ) { :ok, %{ "content" => %{}, "event_id" => "$0:domain", "origin" => "domain", "origin_server_ts" => 1000000, "type" => "m.room.message", "room_id" => "!r:domain", "sender" => "@u:domain", "signatures" => %{} } } iex> Polyjuice.Util.Event.redact( ...> "unknown room version", ...> %{} ...> ) :error """ @spec redact(room_version :: String.t(), event :: map) :: {:ok, map} | :error def redact(room_version, event) when is_binary(room_version) and is_map(event) do try do module = Module.safe_concat(Polyjuice.Util.Event.RoomVersion, room_version) {:ok, apply(module, :redact, [event])} rescue _ -> :error end end end