remove Salmon module
authorAriadne Conill <ariadne@dereferenced.org>
Thu, 17 Oct 2019 23:09:15 +0000 (23:09 +0000)
committerAriadne Conill <ariadne@dereferenced.org>
Fri, 18 Oct 2019 14:50:09 +0000 (14:50 +0000)
lib/pleroma/user/info.ex
lib/pleroma/web/ostatus/feed_representer.ex
lib/pleroma/web/ostatus/ostatus.ex
lib/pleroma/web/ostatus/ostatus_controller.ex
lib/pleroma/web/salmon/salmon.ex [deleted file]
test/web/salmon/salmon_test.exs [deleted file]

index 4b5b43d7fc346fdb77fd67da66205d40b592745c..2d39abcb34582099f983ab2ab4137980be0f8460 100644 (file)
@@ -39,9 +39,6 @@ defmodule Pleroma.User.Info do
     field(:settings, :map, default: nil)
     field(:magic_key, :string, default: nil)
     field(:uri, :string, default: nil)
-    field(:topic, :string, default: nil)
-    field(:hub, :string, default: nil)
-    field(:salmon, :string, default: nil)
     field(:hide_followers_count, :boolean, default: false)
     field(:hide_follows_count, :boolean, default: false)
     field(:hide_followers, :boolean, default: false)
@@ -262,9 +259,6 @@ defmodule Pleroma.User.Info do
       :locked,
       :magic_key,
       :uri,
-      :hub,
-      :topic,
-      :salmon,
       :hide_followers,
       :hide_follows,
       :hide_followers_count,
index b7b97e5050e7ca1a71be92db4d4e9d89ada91d21..fa7f7b564e4f8d5cd4a48952a52a7cbf54e8819f 100644 (file)
@@ -40,8 +40,6 @@ defmodule Pleroma.Web.OStatus.FeedRepresenter do
           {:title, ['#{user.nickname}\'s timeline']},
           {:updated, h.(most_recent_update)},
           {:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]},
-          {:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []},
-          {:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []},
           {:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'],
            []},
           {:author, UserRepresenter.to_simple_form(user)}
index 3dfc9b58000b6e48594de0c005ed3eb581decc17..a858759d33c68c31452230b59e1605b01354cfb5 100644 (file)
@@ -37,10 +37,6 @@ defmodule Pleroma.Web.OStatus do
 
   def feed_path(user), do: "#{user.ap_id}/feed.atom"
 
-  def pubsub_path(user), do: "#{Web.base_url()}/push/hub/#{user.nickname}"
-
-  def salmon_path(user), do: "#{user.ap_id}/salmon"
-
   def remote_follow_path, do: "#{Web.base_url()}/ostatus_subscribe?acct={uri}"
 
   def handle_incoming(xml_string, options \\ []) do
index 20f2d9ddc58ef507ccec9384569cb9ec7cc56008..7466dd8ea9d66773680f4b7110189b22f8dabfc8 100644 (file)
@@ -24,8 +24,6 @@ defmodule Pleroma.Web.OStatus.OStatusController do
     {:ap_routes, params: ["uuid"]} when action in [:object, :activity]
   )
 
-  plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming])
-
   plug(
     Pleroma.Plugs.SetFormatPlug
     when action in [:object, :activity, :notice]
@@ -33,32 +31,6 @@ defmodule Pleroma.Web.OStatus.OStatusController do
 
   action_fallback(:errors)
 
-  defp decode_or_retry(body) do
-    with {:ok, magic_key} <- Pleroma.Web.Salmon.fetch_magic_key(body),
-         {:ok, doc} <- Pleroma.Web.Salmon.decode_and_validate(magic_key, body) do
-      {:ok, doc}
-    else
-      _e ->
-        with [decoded | _] <- Pleroma.Web.Salmon.decode(body),
-             doc <- XML.parse_document(decoded),
-             uri when not is_nil(uri) <- XML.string_from_xpath("/entry/author[1]/uri", doc),
-             {:ok, _} <- Pleroma.Web.OStatus.make_user(uri, true),
-             {:ok, magic_key} <- Pleroma.Web.Salmon.fetch_magic_key(body),
-             {:ok, doc} <- Pleroma.Web.Salmon.decode_and_validate(magic_key, body) do
-          {:ok, doc}
-        end
-    end
-  end
-
-  def salmon_incoming(conn, _) do
-    {:ok, body, _conn} = read_body(conn)
-    {:ok, doc} = decode_or_retry(body)
-
-    Federator.incoming_doc(doc)
-
-    send_resp(conn, 200, "")
-  end
-
   def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid})
       when format in ["json", "activity+json"] do
     ActivityPubController.call(conn, :object)
diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex
deleted file mode 100644 (file)
index 0ffe903..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Salmon do
-  @behaviour Pleroma.Web.Federator.Publisher
-
-  use Bitwise
-
-  alias Pleroma.Activity
-  alias Pleroma.HTTP
-  alias Pleroma.Instances
-  alias Pleroma.Keys
-  alias Pleroma.User
-  alias Pleroma.Web.ActivityPub.Visibility
-  alias Pleroma.Web.Federator.Publisher
-  alias Pleroma.Web.OStatus
-  alias Pleroma.Web.OStatus.ActivityRepresenter
-  alias Pleroma.Web.XML
-
-  require Logger
-
-  def decode(salmon) do
-    doc = XML.parse_document(salmon)
-
-    {:xmlObj, :string, data} = :xmerl_xpath.string('string(//me:data[1])', doc)
-    {:xmlObj, :string, sig} = :xmerl_xpath.string('string(//me:sig[1])', doc)
-    {:xmlObj, :string, alg} = :xmerl_xpath.string('string(//me:alg[1])', doc)
-    {:xmlObj, :string, encoding} = :xmerl_xpath.string('string(//me:encoding[1])', doc)
-    {:xmlObj, :string, type} = :xmerl_xpath.string('string(//me:data[1]/@type)', doc)
-
-    {:ok, data} = Base.url_decode64(to_string(data), ignore: :whitespace)
-    {:ok, sig} = Base.url_decode64(to_string(sig), ignore: :whitespace)
-    alg = to_string(alg)
-    encoding = to_string(encoding)
-    type = to_string(type)
-
-    [data, type, encoding, alg, sig]
-  end
-
-  def fetch_magic_key(salmon) do
-    with [data, _, _, _, _] <- decode(salmon),
-         doc <- XML.parse_document(data),
-         uri when not is_nil(uri) <- XML.string_from_xpath("/entry/author[1]/uri", doc),
-         {:ok, public_key} <- User.get_public_key_for_ap_id(uri),
-         magic_key <- encode_key(public_key) do
-      {:ok, magic_key}
-    end
-  end
-
-  def decode_and_validate(magickey, salmon) do
-    [data, type, encoding, alg, sig] = decode(salmon)
-
-    signed_text =
-      [data, type, encoding, alg]
-      |> Enum.map(&Base.url_encode64/1)
-      |> Enum.join(".")
-
-    key = decode_key(magickey)
-
-    verify = :public_key.verify(signed_text, :sha256, sig, key)
-
-    if verify do
-      {:ok, data}
-    else
-      :error
-    end
-  end
-
-  def decode_key("RSA." <> magickey) do
-    make_integer = fn bin ->
-      list = :erlang.binary_to_list(bin)
-      Enum.reduce(list, 0, fn el, acc -> acc <<< 8 ||| el end)
-    end
-
-    [modulus, exponent] =
-      magickey
-      |> String.split(".")
-      |> Enum.map(fn n -> Base.url_decode64!(n, padding: false) end)
-      |> Enum.map(make_integer)
-
-    {:RSAPublicKey, modulus, exponent}
-  end
-
-  def encode_key({:RSAPublicKey, modulus, exponent}) do
-    modulus_enc = :binary.encode_unsigned(modulus) |> Base.url_encode64()
-    exponent_enc = :binary.encode_unsigned(exponent) |> Base.url_encode64()
-
-    "RSA.#{modulus_enc}.#{exponent_enc}"
-  end
-
-  def encode(private_key, doc) do
-    type = "application/atom+xml"
-    encoding = "base64url"
-    alg = "RSA-SHA256"
-
-    signed_text =
-      [doc, type, encoding, alg]
-      |> Enum.map(&Base.url_encode64/1)
-      |> Enum.join(".")
-
-    signature =
-      signed_text
-      |> :public_key.sign(:sha256, private_key)
-      |> to_string
-      |> Base.url_encode64()
-
-    doc_base64 =
-      doc
-      |> Base.url_encode64()
-
-    # Don't need proper xml building, these strings are safe to leave unescaped
-    salmon = """
-    <?xml version="1.0" encoding="UTF-8"?>
-    <me:env xmlns:me="http://salmon-protocol.org/ns/magic-env">
-      <me:data type="application/atom+xml">#{doc_base64}</me:data>
-      <me:encoding>#{encoding}</me:encoding>
-      <me:alg>#{alg}</me:alg>
-      <me:sig>#{signature}</me:sig>
-    </me:env>
-    """
-
-    {:ok, salmon}
-  end
-
-  def remote_users(%User{id: user_id}, %{data: %{"to" => to} = data}) do
-    cc = Map.get(data, "cc", [])
-
-    bcc =
-      data
-      |> Map.get("bcc", [])
-      |> Enum.reduce([], fn ap_id, bcc ->
-        case Pleroma.List.get_by_ap_id(ap_id) do
-          %Pleroma.List{user_id: ^user_id} = list ->
-            {:ok, following} = Pleroma.List.get_following(list)
-            bcc ++ Enum.map(following, & &1.ap_id)
-
-          _ ->
-            bcc
-        end
-      end)
-
-    [to, cc, bcc]
-    |> Enum.concat()
-    |> Enum.map(&User.get_cached_by_ap_id/1)
-    |> Enum.filter(fn user -> user && !user.local end)
-  end
-
-  @doc "Pushes an activity to remote account."
-  def publish_one(%{recipient: %{info: %{salmon: salmon}}} = params),
-    do: publish_one(Map.put(params, :recipient, salmon))
-
-  def publish_one(%{recipient: url, feed: feed} = params) when is_binary(url) do
-    with {:ok, %{status: code}} when code in 200..299 <-
-           HTTP.post(
-             url,
-             feed,
-             [{"Content-Type", "application/magic-envelope+xml"}]
-           ) do
-      if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since],
-        do: Instances.set_reachable(url)
-
-      Logger.debug(fn -> "Pushed to #{url}, code #{code}" end)
-      {:ok, code}
-    else
-      e ->
-        unless params[:unreachable_since], do: Instances.set_reachable(url)
-        Logger.debug(fn -> "Pushing Salmon to #{url} failed, #{inspect(e)}" end)
-        {:error, "Unreachable instance"}
-    end
-  end
-
-  def publish_one(%{recipient_id: recipient_id} = params) do
-    recipient = User.get_cached_by_id(recipient_id)
-
-    params
-    |> Map.delete(:recipient_id)
-    |> Map.put(:recipient, recipient)
-    |> publish_one()
-  end
-
-  def publish_one(_), do: :noop
-
-  @supported_activities [
-    "Create",
-    "Follow",
-    "Like",
-    "Announce",
-    "Undo",
-    "Delete"
-  ]
-
-  def is_representable?(%Activity{data: %{"type" => type}} = activity)
-      when type in @supported_activities,
-      do: Visibility.is_public?(activity)
-
-  def is_representable?(_), do: false
-
-  @doc """
-  Publishes an activity to remote accounts
-  """
-  @spec publish(User.t(), Pleroma.Activity.t()) :: none
-  def publish(user, activity)
-
-  def publish(%{keys: keys} = user, %{data: %{"type" => type}} = activity)
-      when type in @supported_activities do
-    feed = ActivityRepresenter.to_simple_form(activity, user, true)
-
-    if feed do
-      feed =
-        ActivityRepresenter.wrap_with_entry(feed)
-        |> :xmerl.export_simple(:xmerl_xml)
-        |> to_string
-
-      {:ok, private, _} = Keys.keys_from_pem(keys)
-      {:ok, feed} = encode(private, feed)
-
-      remote_users = remote_users(user, activity)
-
-      salmon_urls = Enum.map(remote_users, & &1.info.salmon)
-      reachable_urls_metadata = Instances.filter_reachable(salmon_urls)
-      reachable_urls = Map.keys(reachable_urls_metadata)
-
-      remote_users
-      |> Enum.filter(&(&1.info.salmon in reachable_urls))
-      |> Enum.each(fn remote_user ->
-        Logger.debug(fn -> "Sending Salmon to #{remote_user.ap_id}" end)
-
-        Publisher.enqueue_one(__MODULE__, %{
-          recipient_id: remote_user.id,
-          feed: feed,
-          unreachable_since: reachable_urls_metadata[remote_user.info.salmon]
-        })
-      end)
-    end
-  end
-
-  def publish(%{id: id}, _), do: Logger.debug(fn -> "Keys missing for user #{id}" end)
-
-  def gather_webfinger_links(%User{} = user) do
-    {:ok, _private, public} = Keys.keys_from_pem(user.keys)
-    magic_key = encode_key(public)
-
-    [
-      %{"rel" => "salmon", "href" => OStatus.salmon_path(user)},
-      %{
-        "rel" => "magic-public-key",
-        "href" => "data:application/magic-public-key,#{magic_key}"
-      }
-    ]
-  end
-
-  def gather_nodeinfo_protocol_names, do: []
-end
diff --git a/test/web/salmon/salmon_test.exs b/test/web/salmon/salmon_test.exs
deleted file mode 100644 (file)
index 153ec41..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Salmon.SalmonTest do
-  use Pleroma.DataCase
-  alias Pleroma.Activity
-  alias Pleroma.Keys
-  alias Pleroma.Repo
-  alias Pleroma.User
-  alias Pleroma.Web.Federator.Publisher
-  alias Pleroma.Web.Salmon
-  import Mock
-  import Pleroma.Factory
-
-  @magickey "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
-
-  @wrong_magickey "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAA"
-
-  @magickey_friendica "RSA.AMwa8FUs2fWEjX0xN7yRQgegQffhBpuKNC6fa5VNSVorFjGZhRrlPMn7TQOeihlc9lBz2OsHlIedbYn2uJ7yCs0.AQAB"
-
-  setup_all do
-    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
-    :ok
-  end
-
-  test "decodes a salmon" do
-    {:ok, salmon} = File.read("test/fixtures/salmon.xml")
-    {:ok, doc} = Salmon.decode_and_validate(@magickey, salmon)
-    assert Regex.match?(~r/xml/, doc)
-  end
-
-  test "errors on wrong magic key" do
-    {:ok, salmon} = File.read("test/fixtures/salmon.xml")
-    assert Salmon.decode_and_validate(@wrong_magickey, salmon) == :error
-  end
-
-  test "it encodes a magic key from a public key" do
-    key = Salmon.decode_key(@magickey)
-    magic_key = Salmon.encode_key(key)
-
-    assert @magickey == magic_key
-  end
-
-  test "it decodes a friendica public key" do
-    _key = Salmon.decode_key(@magickey_friendica)
-  end
-
-  test "encodes an xml payload with a private key" do
-    doc = File.read!("test/fixtures/incoming_note_activity.xml")
-    pem = File.read!("test/fixtures/private_key.pem")
-    {:ok, private, public} = Keys.keys_from_pem(pem)
-
-    # Let's try a roundtrip.
-    {:ok, salmon} = Salmon.encode(private, doc)
-    {:ok, decoded_doc} = Salmon.decode_and_validate(Salmon.encode_key(public), salmon)
-
-    assert doc == decoded_doc
-  end
-
-  test "it gets a magic key" do
-    salmon = File.read!("test/fixtures/salmon2.xml")
-    {:ok, key} = Salmon.fetch_magic_key(salmon)
-
-    assert key ==
-             "RSA.uzg6r1peZU0vXGADWxGJ0PE34WvmhjUmydbX5YYdOiXfODVLwCMi1umGoqUDm-mRu4vNEdFBVJU1CpFA7dKzWgIsqsa501i2XqElmEveXRLvNRWFB6nG03Q5OUY2as8eE54BJm0p20GkMfIJGwP6TSFb-ICp3QjzbatuSPJ6xCE=.AQAB"
-  end
-
-  test_with_mock "it pushes an activity to remote accounts it's addressed to",
-                 Publisher,
-                 [:passthrough],
-                 [] do
-    user_data = %{
-      info: %{
-        salmon: "http://test-example.org/salmon"
-      },
-      local: false
-    }
-
-    mentioned_user = insert(:user, user_data)
-    note = insert(:note)
-
-    activity_data = %{
-      "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
-      "type" => "Create",
-      "actor" => note.data["actor"],
-      "to" => note.data["to"] ++ [mentioned_user.ap_id],
-      "object" => note.data,
-      "published_at" => DateTime.utc_now() |> DateTime.to_iso8601(),
-      "context" => note.data["context"]
-    }
-
-    {:ok, activity} = Repo.insert(%Activity{data: activity_data, recipients: activity_data["to"]})
-    user = User.get_cached_by_ap_id(activity.data["actor"])
-    {:ok, user} = User.ensure_keys_present(user)
-
-    Salmon.publish(user, activity)
-
-    assert called(Publisher.enqueue_one(Salmon, %{recipient_id: mentioned_user.id}))
-  end
-end