aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/pleroma/activity.ex1
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex8
-rw-r--r--lib/pleroma/web/ostatus/ostatus.ex5
-rw-r--r--lib/pleroma/web/ostatus/ostatus_controller.ex21
-rw-r--r--priv/repo/migrations/20171109091239_add_actor_to_activity.exs20
-rw-r--r--priv/repo/migrations/20171109114020_fill_actor_field.exs26
-rw-r--r--priv/repo/migrations/20171109141309_add_sort_index_to_activities.exs8
-rw-r--r--test/support/factory.ex3
-rw-r--r--test/web/activity_pub/activity_pub_test.exs1
-rw-r--r--test/web/ostatus/ostatus_controller_test.exs41
10 files changed, 124 insertions, 10 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index f43b32b56..a35ccc9b4 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -6,6 +6,7 @@ defmodule Pleroma.Activity do
schema "activities" do
field :data, :map
field :local, :boolean, default: true
+ field :actor, :string
has_many :notifications, Notification
timestamps()
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index e7d4c48bd..1624c6545 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
with nil <- Activity.get_by_ap_id(map["id"]),
map <- lazy_put_activity_defaults(map),
:ok <- insert_full_object(map) do
- {:ok, activity} = Repo.insert(%Activity{data: map, local: local})
+ {:ok, activity} = Repo.insert(%Activity{data: map, local: local, actor: map["actor"]})
Notification.create_notifications(activity)
{:ok, activity}
else
@@ -137,7 +137,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_actor(query, %{"actor_id" => actor_id}) do
from activity in query,
- where: fragment("?->>'actor' = ?", activity.data, ^actor_id)
+ where: activity.actor == ^actor_id
end
defp restrict_actor(query, _), do: query
@@ -168,14 +168,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
blocks = info["blocks"] || []
from activity in query,
- where: fragment("not (?->>'actor' = ANY(?))", activity.data, ^blocks)
+ where: fragment("not (? = ANY(?))", activity.actor, ^blocks)
end
defp restrict_blocked(query, _), do: query
def fetch_activities(recipients, opts \\ %{}) do
base_query = from activity in Activity,
limit: 20,
- order_by: [desc: :id]
+ order_by: [fragment("? desc nulls last", activity.id)]
base_query
|> restrict_recipients(recipients)
diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index 308e206c5..b0d2dda5d 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -221,7 +221,7 @@ defmodule Pleroma.Web.OStatus do
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
end
- def make_user(uri) do
+ def make_user(uri, update \\ false) do
with {:ok, info} <- gather_user_info(uri) do
data = %{
name: info["name"],
@@ -231,7 +231,8 @@ defmodule Pleroma.Web.OStatus do
avatar: info["avatar"],
bio: info["bio"]
}
- with %User{} = user <- User.get_by_ap_id(data.ap_id) do
+ with false <- update,
+ %User{} = user <- User.get_by_ap_id(data.ap_id) do
{:ok, user}
else _e -> insert_or_update_user(data)
end
diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex
index 4e3fbb4f6..67688ace4 100644
--- a/lib/pleroma/web/ostatus/ostatus_controller.ex
+++ b/lib/pleroma/web/ostatus/ostatus_controller.ex
@@ -5,6 +5,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
alias Pleroma.Web.OStatus.{FeedRepresenter, ActivityRepresenter}
alias Pleroma.Repo
alias Pleroma.Web.{OStatus, Federator}
+ alias Pleroma.Web.XML
import Ecto.Query
def feed_redirect(conn, %{"nickname" => nickname}) do
@@ -36,10 +37,26 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|> send_resp(200, response)
end
+ 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, user} <- 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, params) do
{:ok, body, _conn} = read_body(conn)
- {:ok, magic_key} = Pleroma.Web.Salmon.fetch_magic_key(body)
- {:ok, doc} = Pleroma.Web.Salmon.decode_and_validate(magic_key, body)
+ {:ok, doc} = decode_or_retry(body)
Federator.enqueue(:incoming_doc, doc)
diff --git a/priv/repo/migrations/20171109091239_add_actor_to_activity.exs b/priv/repo/migrations/20171109091239_add_actor_to_activity.exs
new file mode 100644
index 000000000..2d8b60a91
--- /dev/null
+++ b/priv/repo/migrations/20171109091239_add_actor_to_activity.exs
@@ -0,0 +1,20 @@
+defmodule Pleroma.Repo.Migrations.AddActorToActivity do
+ use Ecto.Migration
+
+ @disable_ddl_transaction true
+
+ def up do
+ alter table(:activities) do
+ add :actor, :string
+ end
+
+ create index(:activities, [:actor, "id DESC NULLS LAST"], concurrently: true)
+ end
+
+ def down do
+ drop index(:activities, [:actor, "id DESC NULLS LAST"])
+ alter table(:activities) do
+ remove :actor
+ end
+ end
+end
diff --git a/priv/repo/migrations/20171109114020_fill_actor_field.exs b/priv/repo/migrations/20171109114020_fill_actor_field.exs
new file mode 100644
index 000000000..255ca46d5
--- /dev/null
+++ b/priv/repo/migrations/20171109114020_fill_actor_field.exs
@@ -0,0 +1,26 @@
+defmodule Pleroma.Repo.Migrations.FillActorField do
+ use Ecto.Migration
+
+ alias Pleroma.{Repo, Activity}
+
+ def up do
+ max = Repo.aggregate(Activity, :max, :id)
+ if max do
+ IO.puts("#{max} activities")
+ chunks = 0..(round(max / 10_000))
+
+ Enum.each(chunks, fn (i) ->
+ min = i * 10_000
+ max = min + 10_000
+ execute("""
+ update activities set actor = data->>'actor' where id > #{min} and id <= #{max};
+ """)
+ |> IO.inspect
+ end)
+ end
+ end
+
+ def down do
+ end
+end
+
diff --git a/priv/repo/migrations/20171109141309_add_sort_index_to_activities.exs b/priv/repo/migrations/20171109141309_add_sort_index_to_activities.exs
new file mode 100644
index 000000000..2d21c56ca
--- /dev/null
+++ b/priv/repo/migrations/20171109141309_add_sort_index_to_activities.exs
@@ -0,0 +1,8 @@
+defmodule Pleroma.Repo.Migrations.AddSortIndexToActivities do
+ use Ecto.Migration
+ @disable_ddl_transaction true
+
+ def change do
+ create index(:activities, ["id desc nulls last"], concurrently: true)
+ end
+end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index dabb95141..9bbf11f08 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -51,7 +51,8 @@ defmodule Pleroma.Factory do
}
%Pleroma.Activity{
- data: data
+ data: data,
+ actor: data["actor"]
}
end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 2cd33d623..f50509b63 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -52,6 +52,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "removes doubled 'to' recipients" do
{:ok, activity} = ActivityPub.create(["user1", "user1", "user2"], %User{ap_id: "1"}, "", %{})
assert activity.data["to"] == ["user1", "user2"]
+ assert activity.actor == "1"
end
end
diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs
index 77bc202fe..20d17d41f 100644
--- a/test/web/ostatus/ostatus_controller_test.exs
+++ b/test/web/ostatus/ostatus_controller_test.exs
@@ -1,9 +1,41 @@
defmodule Pleroma.Web.OStatus.OStatusControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
- alias Pleroma.User
+ alias Pleroma.{User, Repo}
alias Pleroma.Web.OStatus.ActivityRepresenter
+ test "decodes a salmon", %{conn: conn} do
+ user = insert(:user)
+ salmon = File.read!("test/fixtures/salmon.xml")
+ conn = conn
+ |> put_req_header("content-type", "application/atom+xml")
+ |> post("/users/#{user.nickname}/salmon", salmon)
+
+ assert response(conn, 200)
+ end
+
+ test "decodes a salmon with a changed magic key", %{conn: conn} do
+ user = insert(:user)
+ salmon = File.read!("test/fixtures/salmon.xml")
+ conn = conn
+ |> put_req_header("content-type", "application/atom+xml")
+ |> post("/users/#{user.nickname}/salmon", salmon)
+
+ assert response(conn, 200)
+
+ # Set a wrong magic-key for a user so it has to refetch
+ salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
+ info = salmon_user.info
+ |> Map.put("magic_key", "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB") # Wrong key
+ Repo.update(User.info_changeset(salmon_user, %{info: info}))
+
+ conn = build_conn()
+ |> put_req_header("content-type", "application/atom+xml")
+ |> post("/users/#{user.nickname}/salmon", salmon)
+
+ assert response(conn, 200)
+ end
+
test "gets a feed", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
@@ -42,3 +74,10 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
assert response(conn, 200)
end
end
+
+defmodule Pleroma.Web.OStatusMock do
+ import Pleroma.Factory
+ def handle_incoming(_doc) do
+ insert(:note_activity)
+ end
+end