+ {:ok, user}
+ end
+
+ def html_filter_policy(%User{info: %{"no_rich_text" => true}}) do
+ Pleroma.HTML.Scrubber.TwitterText
+ end
+
+ def html_filter_policy(_), do: nil
+
+ def get_or_fetch_by_ap_id(ap_id) do
+ user = get_by_ap_id(ap_id)
+
+ if !is_nil(user) and !User.needs_update?(user) do
+ user
+ else
+ ap_try = ActivityPub.make_user_from_ap_id(ap_id)
+
+ case ap_try do
+ {:ok, user} ->
+ user
+
+ _ ->
+ case OStatus.make_user(ap_id) do
+ {:ok, user} -> user
+ _ -> {:error, "Could not fetch by AP id"}
+ end
+ end
+ end
+ end
+
+ def get_or_create_instance_user do
+ relay_uri = "#{Pleroma.Web.Endpoint.url()}/relay"
+
+ if user = get_by_ap_id(relay_uri) do
+ user
+ else
+ changes =
+ %User{}
+ |> cast(%{}, [:ap_id, :nickname, :local])
+ |> put_change(:ap_id, relay_uri)
+ |> put_change(:nickname, nil)
+ |> put_change(:local, true)
+ |> put_change(:follower_address, relay_uri <> "/followers")
+
+ {:ok, user} = Repo.insert(changes)
+ user
+ end
+ end
+
+ # AP style
+ def public_key_from_info(%{
+ "source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
+ }) do
+ key =
+ :public_key.pem_decode(public_key_pem)
+ |> hd()
+ |> :public_key.pem_entry_decode()
+
+ {:ok, key}
+ end
+
+ # OStatus Magic Key
+ def public_key_from_info(%{"magic_key" => magic_key}) do
+ {:ok, Pleroma.Web.Salmon.decode_key(magic_key)}
+ end
+
+ def get_public_key_for_ap_id(ap_id) do
+ with %User{} = user <- get_or_fetch_by_ap_id(ap_id),
+ {:ok, public_key} <- public_key_from_info(user.info) do
+ {:ok, public_key}
+ else
+ _ -> :error
+ end
+ end
+
+ defp blank?(""), do: nil
+ defp blank?(n), do: n
+
+ def insert_or_update_user(data) do
+ data =
+ data
+ |> Map.put(:name, blank?(data[:name]) || data[:nickname])
+
+ cs = User.remote_user_creation(data)
+ Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
+ end
+
+ def ap_enabled?(%User{local: true}), do: true
+ def ap_enabled?(%User{info: info}), do: info["ap_enabled"]
+ def ap_enabled?(_), do: false
+
+ def get_or_fetch(uri_or_nickname) do
+ if String.starts_with?(uri_or_nickname, "http") do
+ get_or_fetch_by_ap_id(uri_or_nickname)
+ else
+ get_or_fetch_by_nickname(uri_or_nickname)
+ end
+ end
+
+ # wait a period of time and return newest version of the User structs
+ # this is because we have synchronous follow APIs and need to simulate them
+ # with an async handshake
+ def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do
+ with %User{} = a <- Repo.get(User, a.id),
+ %User{} = b <- Repo.get(User, b.id) do
+ {:ok, a, b}
+ else
+ _e ->
+ :error
+ end
+ end
+
+ def wait_and_refresh(timeout, %User{} = a, %User{} = b) do
+ with :ok <- :timer.sleep(timeout),
+ %User{} = a <- Repo.get(User, a.id),
+ %User{} = b <- Repo.get(User, b.id) do
+ {:ok, a, b}
+ else
+ _e ->
+ :error
+ end