Merge branch 'develop' into dtluna/pleroma-refactor/1
authorRoger Braun <roger@rogerbraun.net>
Fri, 5 May 2017 09:46:59 +0000 (11:46 +0200)
committerRoger Braun <roger@rogerbraun.net>
Fri, 5 May 2017 09:46:59 +0000 (11:46 +0200)
12 files changed:
1  2 
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/ostatus/activity_representer.ex
lib/pleroma/web/ostatus/feed_representer.ex
lib/pleroma/web/ostatus/ostatus_controller.ex
lib/pleroma/web/router.ex
lib/pleroma/web/salmon/salmon.ex
lib/pleroma/web/twitter_api/representers/activity_representer.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
lib/pleroma/web/web.ex
lib/pleroma/web/web_finger/web_finger.ex
lib/pleroma/web/websub/websub.ex

index 65925caed0aa3eee377b8264bbaa277e269b4bf9,01cbfe796379d864b997796a3879e731095ed4c9..23be6276ebe6abce6bffa9567d4c5a7d6225b600
@@@ -1,8 -1,9 +1,10 @@@
  defmodule Pleroma.User do
    use Ecto.Schema
 -  import Ecto.Changeset
 -  import Ecto.Query
 -  alias Pleroma.{Repo, User, Activity, Object}
++
 +  import Ecto.{Changeset, Query}
 +  alias Pleroma.{Repo, User, Object, Web}
 +  alias Comeonin.Pbkdf2
+   alias Pleroma.Web.OStatus
  
    schema "users" do
      field :bio, :string
      field :password_hash, :string
      field :password, :string, virtual: true
      field :password_confirmation, :string, virtual: true
 -    field :following, { :array, :string }, default: []
 +    field :following, {:array, :string}, default: []
      field :ap_id, :string
      field :avatar, :map
+     field :local, :boolean, default: true
+     field :info, :map, default: %{}
  
      timestamps()
    end
index 02255e0a427c7fae327a92da12e3b31e2cee9981,1816b2e666c8476ec43491772b26978e40ea01c5..d7b490088da2902fe5cb9145c83cf746e72287b9
@@@ -1,9 -1,9 +1,9 @@@
  defmodule Pleroma.Web.ActivityPub.ActivityPub do
 -  alias Pleroma.Repo
 -  alias Pleroma.{Activity, Object, Upload, User}
 +  alias Pleroma.{Activity, Repo, Object, Upload, User, Web}
 +  alias Ecto.{Changeset, UUID}
    import Ecto.Query
  
-   def insert(map) when is_map(map) do
+   def insert(map, local \\ true) when is_map(map) do
      map = map
      |> Map.put_new_lazy("id", &generate_activity_id/0)
      |> Map.put_new_lazy("published", &make_date/0)
        map
      end
  
-     Repo.insert(%Activity{data: map})
+     Repo.insert(%Activity{data: map, local: local})
+   end
+   def create(to, actor, context, object, additional \\ %{}, published \\ nil, local \\ true) do
+     published = published || make_date()
+     activity = %{
+       "type" => "Create",
+       "to" => to |> Enum.uniq,
+       "actor" => actor.ap_id,
+       "object" => object,
+       "published" => published,
+       "context" => context
+     }
+     |> Map.merge(additional)
+     with {:ok, activity} <- insert(activity, local) do
+       if actor.local do
+         Pleroma.Web.Federator.enqueue(:publish, activity)
+        end
+       {:ok, activity}
+     end
    end
  
 -  def like(%User{ap_id: ap_id} = user, %Object{data: %{ "id" => id}} = object) do
 +  def like(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object) do
      cond do
        # There's already a like here, so return the original activity.
        ap_id in (object.data["likes"] || []) ->
        query
      end
  
 -    Repo.all(query)
 -    |> Enum.reverse
 +    Enum.reverse(Repo.all(query))
    end
  
-   def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object) do
+   def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, local \\ true) do
      data = %{
        "type" => "Announce",
        "actor" => ap_id,
index d7ea6132103b7eb96bc49ed40c7d022354e8982f,41a42b7cbb92c2d5d2cb2f55ab3ed813dcce50ca..88781626c889a20ddebd11953592bc3025f1c8bd
@@@ -19,9 -49,86 +49,86 @@@ defmodule Pleroma.Web.OStatus.ActivityR
        {:title, ['New note by #{user.nickname}']},
        {:content, [type: 'html'], h.(activity.data["object"]["content"])},
        {:published, h.(inserted_at)},
-       {:updated, h.(updated_at)}
-     ] ++ attachments
+       {:updated, h.(updated_at)},
+       {:"ostatus:conversation", [], h.(activity.data["context"])},
+       {:link, [href: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
+       {:link, [type: ['application/atom+xml'], href: h.(activity.data["object"]["id"]), rel: 'self'], []}
+     ] ++ attachments ++ in_reply_to ++ author ++ mentions
+   end
+   def to_simple_form(%{data: %{"type" => "Like"}} = activity, user, with_author) do
+     h = fn(str) -> [to_charlist(str)] end
+     updated_at = activity.updated_at
+     |> NaiveDateTime.to_iso8601
+     inserted_at = activity.inserted_at
+     |> NaiveDateTime.to_iso8601
+     in_reply_to = get_in_reply_to(activity.data)
+     author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
+     mentions = activity.data["to"] |> get_mentions
+     [
+       {:"activity:verb", ['http://activitystrea.ms/schema/1.0/favorite']},
+       {:id, h.(activity.data["id"])},
+       {:title, ['New favorite by #{user.nickname}']},
+       {:content, [type: 'html'], ['#{user.nickname} favorited something']},
+       {:published, h.(inserted_at)},
+       {:updated, h.(updated_at)},
+       {:"activity:object", [
+         {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
+         {:id, h.(activity.data["object"])}, # For notes, federate the object id.
+       ]},
+       {:"ostatus:conversation", [], h.(activity.data["context"])},
+       {:link, [href: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
+       {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
+       {:"thr:in-reply-to", [ref: to_charlist(activity.data["object"])], []}
+     ] ++ author ++ mentions
+   end
+   def to_simple_form(%{data: %{"type" => "Announce"}} = activity, user, with_author) do
+     h = fn(str) -> [to_charlist(str)] end
+     updated_at = activity.updated_at
+     |> NaiveDateTime.to_iso8601
+     inserted_at = activity.inserted_at
+     |> NaiveDateTime.to_iso8601
+     in_reply_to = get_in_reply_to(activity.data)
+     author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
+     retweeted_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+     retweeted_user = User.get_cached_by_ap_id(retweeted_activity.data["actor"])
+     retweeted_xml = to_simple_form(retweeted_activity, retweeted_user, true)
+     mentions = activity.data["to"] |> get_mentions
+     [
+       {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
+       {:"activity:verb", ['http://activitystrea.ms/schema/1.0/share']},
+       {:id, h.(activity.data["id"])},
+       {:title, ['#{user.nickname} repeated a notice']},
+       {:content, [type: 'html'], ['RT #{retweeted_activity.data["object"]["content"]}']},
+       {:published, h.(inserted_at)},
+       {:updated, h.(updated_at)},
+       {:"ostatus:conversation", [], h.(activity.data["context"])},
+       {:link, [href: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
+       {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
+       {:"activity:object", retweeted_xml}
+     ] ++ mentions ++ author
+   end
+   def wrap_with_entry(simple_form) do
+     [{
+       :entry, [
+         xmlns: 'http://www.w3.org/2005/Atom',
+         "xmlns:thr": 'http://purl.org/syndication/thread/1.0',
+         "xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
+         "xmlns:poco": 'http://portablecontacts.net/spec/1.0',
+         "xmlns:ostatus": 'http://ostatus.org/schema/1.0'
+       ], simple_form
+     }]
    end
  
-   def to_simple_form(_, _), do: nil
 -  def to_simple_form(_,_,_), do: nil
++  def to_simple_form(_, _, _), do: nil
  end
Simple merge
Simple merge
index b5857282930a1e9e9226e9b80a6c7ef2d6162ea1,bfaabb4e424eee5f08bb2ae41af6aa7a1c55de0b..4d7ea0c5cfb21187c542df55ae6dec6376fa067f
@@@ -1,8 -1,8 +1,9 @@@
  defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
    use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
    alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ObjectRepresenter}
 -  alias Pleroma.Activity
 +  alias Pleroma.{Activity, User}
 +  alias Calendar.Strftime
+   alias Pleroma.Web.TwitterAPI.TwitterAPI
  
    defp user_by_ap_id(user_list, ap_id) do
      Enum.find(user_list, fn (%{ap_id: user_id}) -> ap_id == user_id end)
@@@ -90,9 -97,9 +97,9 @@@
        "is_local" => true,
        "is_post_verb" => true,
        "created_at" => created_at,
 -      "in_reply_to_status_id" => activity.data["object"]["inReplyToStatusId"],
 +      "in_reply_to_status_id" => object["inReplyToStatusId"],
-       "statusnet_conversation_id" => object["statusnetConversationId"],
+       "statusnet_conversation_id" => conversation_id,
 -      "attachments" => (activity.data["object"]["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts),
 +      "attachments" => (object["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts),
        "attentions" => attentions,
        "fave_num" => like_count,
        "repeat_num" => announcement_count,
Simple merge
index 3d6ca4e05c64c2d46dc32c2b7de4f44bff265e8a,5fa69c2c825b0179eeabd9bad069dcae87056f54..1eb26a89fd19d5b355ac996b4407afee41705b50
@@@ -1,13 -1,15 +1,16 @@@
  defmodule Pleroma.Web.WebFinger do
-   alias Pleroma.{User, XmlBuilder}
-   alias Pleroma.{Web, Web.OStatus}
 -  alias Pleroma.XmlBuilder
 -  alias Pleroma.{Repo, User}
++
++  alias Pleroma.{Repo, User, XmlBuilder}
++  alias Pleroma.Web
+   alias Pleroma.Web.{XML, Salmon, OStatus}
+   require Logger
  
 -  def host_meta() do
 -    base_url  = Pleroma.Web.base_url
 +  def host_meta do
 +    base_url  = Web.base_url
      {
 -      :XRD, %{ xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0" },
 +      :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
        {
 -        :Link, %{ rel: "lrdd", type: "application/xrd+xml", template: "#{base_url}/.well-known/webfinger?resource={uri}"  }
 +        :Link, %{rel: "lrdd", type: "application/xrd+xml", template: "#{base_url}/.well-known/webfinger?resource={uri}"}
        }
      }
      |> XmlBuilder.to_doc
index ba699db2462c5b31cb9a5df6d1c82cef77b0170b,ba86db50e6ede23f17e682783159099531a3e5e4..afbe944c57996e0b08670c7598c7161b338fa1f3
@@@ -1,9 -1,10 +1,11 @@@
  defmodule Pleroma.Web.Websub do
 +  alias Ecto.Changeset
    alias Pleroma.Repo
-   alias Pleroma.Web.Websub.WebsubServerSubscription
+   alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
    alias Pleroma.Web.OStatus.FeedRepresenter
-   alias Pleroma.Web.OStatus
+   alias Pleroma.Web.{XML, Endpoint, OStatus}
+   alias Pleroma.Web.Router.Helpers
+   require Logger
  
    import Ecto.Query
  
      where: sub.topic == ^topic and sub.state == "active"
      subscriptions = Repo.all(query)
      Enum.each(subscriptions, fn(sub) ->
 -      response = FeedRepresenter.to_simple_form(user, [activity], [user])
 +      response = user
 +      |> FeedRepresenter.to_simple_form([activity], [user])
        |> :xmerl.export_simple(:xmerl_xml)
+       |> to_string
  
-       signature = Base.encode16(:crypto.hmac(:sha, sub.secret, response))
+       signature = sign(sub.secret || "", response)
+       Logger.debug("Pushing to #{sub.callback}")
 +
        HTTPoison.post(sub.callback, response, [
              {"Content-Type", "application/atom+xml"},
              {"X-Hub-Signature", "sha1=#{signature}"}
          callback: callback
        }
  
 -      change = Ecto.Changeset.change(subscription, data)
 +      change = Changeset.change(subscription, data)
        websub = Repo.insert_or_update!(change)
  
 -      change = Ecto.Changeset.change(websub, %{valid_until: NaiveDateTime.add(websub.updated_at, lease_time)})
 +      change = Changeset.change(websub, %{valid_until:
 +                                          NaiveDateTime.add(websub.updated_at, lease_time)})
        websub = Repo.update!(change)
  
-       # Just spawn that for now, maybe pool later.
-       spawn(fn -> @websub_verifier.verify(websub) end)
+       Pleroma.Web.Federator.enqueue(:verify_websub, websub)
  
        {:ok, websub}
      else {:error, reason} ->
    end
  
    defp get_subscription(topic, callback) do
 -    Repo.get_by(WebsubServerSubscription, topic: topic, callback: callback) || %WebsubServerSubscription{}
 +    Repo.get_by(WebsubServerSubscription, topic: topic, callback: callback) ||
 +      %WebsubServerSubscription{}
    end
  
+   # Temp hack for mastodon.
+   defp lease_time(%{"hub.lease_seconds" => ""}) do
+     {:ok, 60 * 60 * 24 * 3} # three days
+   end
    defp lease_time(%{"hub.lease_seconds" => lease_seconds}) do
      {:ok, String.to_integer(lease_seconds)}
    end